1.我们可以使用一种标号,这种标号不但表示内存单元的地址,还表示了内存单元的长度,即表示在此标号处的单元,是一个字节单元,还是字单元,还是双字单元。如
a:db 1,2,3,4,5,6,7,8 改写为 a db 1,2,3,4,5,6,7,8
b:dw 0 改变为 b dw 0
使用不带“:”的标号,它们是同时描述内存地址和单元长度的标号。这种标号包含了对单元长度的描述,所以,在指令中,它可以代表一个段中的内存单元。
2.使用这种包含单元长度的标号,可以使我们以简洁的形式访问内存中的数据。以后,我们将这种标号称为数据标号,它标记了存储数据的单元的地址和长度。它不同于仅仅表示地址的地址标号。
在其他段中使用数据标号
1.一般来说,我们不在代码段中定义数据,而是将数据定义到其他段中。在其他段中,我们也可以使用数据标号来描述存储数据的单元的地址和长度。
2.注意,在后面加有“:”的地址标号,只能在代码段中使用,不能再其他段中使用。
3.注意,如果想在代码段中直接用数据标号访问数据,则需要用伪指令assume将标号所在的段和一个段寄存器联系起来。否则编译器在编译的时候,无法确定标号的段地址在哪一个寄存器中。当然,这种联系是编译器需要的,但绝对不是说,我们因为编译器的工作需要,用assume指令将段寄存器和某个段相联系,段寄存器中就会真的存放该段的地址。我们在程序中还要使用指令对段寄存器进行设置。
4.可以将标号当做数据来定义,此时,编译器将标号所表示的地址当做数据的值。
5.seg操作符,功能为取得某一标号的段地址。
附上一个用直接定址表来计算sin(x)的程序:
1 assume cs:code 2 code segment 3 start: 4 mov al,60 5 call showsin 6 7 mov ax,4c00h 8 int 21h 9 10 showsin: 11 jmp short show 12 table dw ag0,ag30,ag60,ag90,ag120,ag150,ag180 13 ag0 db ‘0‘,0 14 ag30 db ‘0.5‘, 0 15 ag60 db ‘0.866‘, 0 16 ag90 db ‘1‘,0 17 ag120 db ‘0.866‘,0 18 ag150 db ‘0.5‘,0 19 ag180 db ‘0‘,0 20 21 show : 22 push bx 23 push es 24 push si 25 mov bx,0b800h 26 mov es,bx 27 28 mov ah,0 29 mov bl,30 30 div bl 31 mov bl,al ;角度/30作为table偏移,商al放到bl中 32 mov bh,0 33 add bx ,bx ;因为dw每个占2字节,0-1,,1-2 ... 34 mov bx,table[bx] 35 mov si,160*23+40*2 36 shows: 37 mov ah,cs:[bx] 38 cmp ah,0 ;ah是否为0,是则跳转至showret 39 je showret 40 mov es:[si],ah 41 inc bx 42 add si,2 43 jmp shows 44 45 showret: 46 pop si 47 pop es 48 pop bx 49 ret 50 51 52 53 code ends 54 end start
时间: 2024-10-07 05:26:59