汇编语言 —— 直接定址表


我们一直在代码段中使用标号来标记指令、数据、段的起始地址。

text

assume cs:code

code segment

    a: db 1,2,3,4,5,6,7,8
    b: dw 0

    start:
        ...
        ...

code ends

end start

上述案例中,code、a、b、start、s 都是标号。这些标号仅仅表示内存单元的地址。

我们还可以使用一种标号,这种标号不但表示内存单元的地址,还表示了内存单元的长度,即表示在此标号处的单元,是一个字节单元,还是字单元,还是双字单元。

text

assume cs:code

code segment

    a db 1,2,3,4,5,6,7,8
    b dw 0

    start:
        ...
        ...

code ends

end start

在 code 段中使用的标号 a、b 后面没有 “:”,它们是同时描述内存地址和单元长度的标号。标号 a,描述了地址 code:0,和从这个地址开始,以后的内存单元都是字节单元;而标号 b 描述了地址 code:8,和从这个地址开始,以后的内存单元都是字单元。

我们将这种标号称数据标号,它标记了存储数据的单元的地址和长度。它不同于仅仅表示地址的地址标号。

地址标号只能在代码段中使用,不能在其他段中使用。


一般来说,我们不在代码段中定义数据,而是将数据定义到其他段中。在其他段中,我们也可以使用数据标号来描述存储数据的单元的地址和长度。

下面的程序将 data 段中 a 标号处的 8 个数据累加,结果存储到 b 标号处的字中:

text

assume cs:code, ds:data         ; 用 assume 将寄存器与 data 相联

data segment
    a db 1,2,3,4,5,6,7,8
    b dw 0
data ends

code segment
    start:
            mov ax, data
            mov ds, ax          ; 用指令对段寄存器进行设置

            mov si, 0
            mov cx, 8
        s:
            mov al, a[si]       ; 直接使用数据标号 a 访问数据
            mov ah, 0
            add b, ax           ; 直接使用数据标号 b 访问数据
            inc si
            loop s

            mov ax, 4c00h
            int 21h
code ends

end start

我们要在代码段 code 中用 data 段中的数据标号 a、b 访问数据,则必须用 assume 将一个寄存器和 data 段相联。


利用表,在两个数据集合之间建立一种映射关系,使我们可以用查表的方法根据给出的数据得到其在另一集合中的对应数据。这样做的目的一般有 3 个。

  1. 为了算法的清晰和简洁;
  2. 为了加快运算速度;
  3. 为了使程序易于扩充。

用查表的依据数据,直接计算出所要查找的元素在表中的位置,可以通过依据数据,直接计算出所要找的元素的位置的表,我们称其为直接定址表。


我们可以在直接定址表中存储子程序的地址,从而方便地实现不同子程序的调用。