直接定址法
1.描述了单元长度的标号
我们一直在代码段中使用标号来标记指令、数据、段的起始地址。比如:下面的程序(将code段中a标号处的8个数据累加,结果存放在b标号处的字中)
assume cs:code
code segment
a : db 1,2,3,4,5,6,7,8 ;在后面加有“:”的地址标号,只能在代码段中使用,不能在其他段中使用。
b : dw 0
start :mov si,offset a
mov bx,offset b
mov cx,8
s : mov al,cs:[si]
mov ah,0
add cs:[bx],ax
inc si
loop s
mov ax,4c00h
int 21h
code ends
end start
;程序中,code、a、b、start、s都是标号。这些标号仅仅表示了内存单元的地址
但是我们还是可以使用一种标号,这种标号不但可以表示内存单元地址,还表示了内存单元的长度,即表示在此标号处的单元,是一个字节单元,还是字单元,还是双字单元。所以,上面的代码还可以写成:
;描述了单位长度的标号
assume cs:code
code segment
a db 1,2,3,4,5,6,7,8 ;标号a、b后面没有":",因此它们是可以同时描述内存地址和单元长度的标号。
;标号a,描述了地址code:0,和从这个地址开始,以后的内存单元都是字节单元
b dw 0 ;标号b描述了地址code:8,和从这个地址开始,以后的内存单元都是字单元。
start : mov si,0
mov cx,8
s : mov al,a[si]
mov ah,0
add b,ax
inc si
loop s
mov ax,4c00h
int 21h
code ends
end start
2.在其他段中使用数据标号
一般来说,我们不在代码段中定义数据,而是将数据定义到其他段中。其他段中,我们也可以使用数据标号来描述存储数据的单元的地址和长度,比如下面的程序:将data段中a标号处的8个数据累加,结果存在b标记处的字中
;注意:后面加:的地址标号,只能在代码段中使用,不能在其他段中使用
assume cs:code,ds:data ;用伪指令assume将标号所在的段和一个段寄存器联系起来(编译器需要)
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 ;真正确定ds寄存器
mov si,0
mov cx,8
s: mov al,a[si] ;编译为:mov al,[si+0] 默认所访问单元的段地址在ds
mov ah,0
add b,ax ;编译为:add [8],ax
inc si
loop s
mov ax,4c00h
int 21h
code ends
end start
data segment
a db 1,2,3,4,5,6,7,8
b dw 0
c dw a, b ;等价于c dw offset a, offset b
;数据标号c处存储的两个字型数据为标号a、b 的偏移地址
data ends
data segment
a db 1,2,3,4,5,6,7,8
b dw 0
c dd a,b ;等价于c dw offset a, seg a, offset b, seg b 注:seg操作符,功能为取得某一标号的段地址
;数据标号c处存储的两个双字型数据为标号a的偏移地址和段地址、标号b 的偏移地址和段地址
data ends
3.直接定址表
建立一张表,表中依次存储“0”~“F”,我们可以通过数值0 ~15直接查找到对应的字符
assume cs:code
code segment
start:
mov al,0eh
call showbyte
mov ax,4c00h
int 21h
;子程序:
;用al传送要显示的数据
showbyte:
jmp short show
table db '0123456789ABCDEF' ;字符表
show: push bx
push es
mov ah,al
shr ah,1
shr ah,1
shr ah,1
shr ah,1 ;右移4位,ah中得到高4位的值
and al,00001111b ;al中为低4位的值
mov bl,ah
mov bh,0
mov ah,table[bx] ;用高4位的值作为相对于table的偏移,取得对应的字符
mov bx,0b800h
mov es,bx
mov es:[160*12+40*2],ah
mov bl,al
mov bh,0
mov al,table[bx] ;用低4位的值作为相对于table的偏移,取得对应的字符
mov es:[160*12+40*2+2],al
pop es
pop bx
ret
code ends
end start