1.数据标号
关于标号:
在汇编代码中,可以用标号表示该段代码的内存地址;
标号格式为,标号名加冒号 ->"start:"
例如:下面的代码中 start: 就是标号;
start:mov ax,0
mov bx,ax
关于数据标号:
普通的标号只能表示内存地址;
数据标号即可表示内存地址,也可表示内存单元的长度;
使用数据标号可以以更加简洁的方式访问内存中的数据;
数据标号的格式为:只有标号名,没有冒号
例如:使用数据标号,实现数值的累加
assume cs:code
code segment
a db 1,2,3,4,5
b dw 0
start:mov si,0
mov cx,5
s: mov al,a[si]
mov ah,0
add b,ax
inc si
loop s
mov ax,4c00h
int 21h
code ends
end start
在上面的代码中,a、b为数据标号;
可以使用类似a[si] 的方式获取标号a处偏移量为si的值的数据;
注意数据标号的类型,例如上面的a时字节型数据单元,不能使用字型单元的mov指令;
2.在其它段中使用数据标号
普通的标号只能在代码段中使用;例如标号"s:"出现在数据段中会报错;
一般情况下会将数据段和代码段分开,并且在数据段中保存数据,在代码段中保存代码,此时普通标号无法满足访问数据的需要;
使用数据标号可以解决标号无法在其它段中的问题;
例如:
assume cs:code,ds:data
data segment
a db 1,2,3,4,5
b dw 0
data ends
code segment
start: mov ax,data
mov ds,ax
mov si,0
mov cx,5
s: mov al,a[si]
mov ah,0
add b,ax
inc si
loop s
mov ax,4c00h
int 21h
code ends
end start
注意:
如果想要在代码段中使用标号访问数据段,需要使用伪指令assume将段寄存器和标号所在段关联;
assume的关联是为了让编译器可以识别标号所在段的段地址在哪个寄存器中,实际代码中还需要将段寄存器指向对应的段;
比如:上面的代码中,想要使用数据标号a、b,用assume伪指令关联ds和data;
但assume只是将关联告诉了编译器,实际的代码段中还需要用mov ax,data和mov ds,ax指令来将ds指向data;
使用数据标号:储存两个数据标号的段地址和偏移地址
data segment
a db 1,2,3,4,5
b dw 0
c dd a,b
data ends
相当于:
data segment
a db 1,2,3,4,5
b dw 0
c dw offset a,seg a,offset b,seg b
data ends
seg功能为取得某一标号的段地址;
3.直接定址表
在编程时常会遇到一些比如用给出的数据通过计算来获得结果的问题;
例如:将一个数转换成十六进制显示;
当一次需要转换的数字很多时,需要多次进行重复的计算转换;
为了简化操作,可以将问题转换为用给出的数据作为查表的依据,通过查表获得结果;
具体操作是,建一张数据和结果映射表;用数据为条件,计算结果在表中的位置,也就获取了结果;
例如:将0~F对应的ascii码放入一个数据段中,根据所给数值的大小来计算该数值对应的ascii在数据段中的地址;这样就不用每次都做将数值转换成ascii的操作;
这种可以依据数据,直接计算出所要找的元素的位置的表称为直接定址表;
直接定址表的应用示例代码:
assume cs:code
code segment
start: mov al,15
call showbyte
mov ax,4c00h
int 21h
showbyte: jmp short show
table db '0123456789ABCDEF'
show: push bx
push es
mov ah,al ;用al传送要显示的数据
shr ah,1 ;右移一位
shr ah,1
shr ah,1
shr ah,1
and al,00001111b
mov bl,ah
mov bh,0
mov ah,table[bx]
mov bx,0b800h
mov es,bx
mov es:[160*12+40*2],ah ;显示高4位
mov bl,al
mov bh,0
mov al,table[bx]
mov es:[160*12+40*2+2],al ;显示低4位
pop es
pop bx
ret
code ends
end start
4.程序入口地址的直接定址表
例如:传入0、1、2分别调用不同的子程序
assume cs:code
code segment
start:mov ah,2 ;功能参数
mov al,1 ;颜色参数
call setscreen
mov ax,4c00h
int 21h
setscreen: jmp short set
table dw sub1,sub2,sub3
set: push bx
cmp ah,2
ja sret
mov bl,ah
add bx,bx
call word ptr table[bx]
sret: pop bx
ret
sub1: push bx ;子程序1,用来将屏幕清空
push cx
push es
mov bx,0b800h
mov es,bx
mov bx,0
mov cx,80*25
sub1s: mov byte ptr es:[bx],' '
add bx,2
loop sub1s
pop es
pop cx
pop bx
ret
sub2: push bx ;子程序2,切换字体颜色
push cx
push es
mov bx,0b800h
mov es,bx
mov bx,1
mov cx,80*25
sub2s: and byte ptr es:[bx],11111000b ;第0、1、2位控制字体颜色
or byte ptr es:[bx],al
add bx,2
loop sub2s
pop es
pop cx
pop bx
ret
sub3: push bx
push cx
push es
mov cl,4 ;al参数左移4位,来对应控制颜色的位
shl al,cl
mov bx,0b800h
mov es,bx
mov bx,1
mov cx,25*80
sub3s: and byte ptr es:[bx],10001111b ;第4、5、6位控制背景色
or byte ptr es:[bx],al
add bx,2
loop sub3s
pop es
pop cx
pop bx
ret
code ends
end start