汇编16:直接定址表

直接定址表

数据标号

之前我们使用的标号形式:

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

start:	...

这个标号仅仅代表内存单元的地址。

我们还可以使用同时描述内存地址和单元长度的标号,即数据标号(没有冒号),如:

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

它代表a之后的单元都是字节单元,b之后的单元都是字单元。当指令中出现标号a或b的时候,会同时代表地址和单元长度信息,如果出现字节匹配字的情况出现会报错:

mov ax,b			等价于			mov ax,cs:[8]
mov b,2				等价于			mov word ptr cs:[8],2
mov al,a[si]		        等价于			mov al,cs:0[si]
mov al,a[bx+si+3]	        等价于			mov al,cs:0[bx+si+3]

这个装段地址的cs是可以自由设置的。

如在下列程序中:

assume cs:code,ds: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]
	mov ah,0
	add b,ax
	inc si
	loop s
		
	mov ax,4c00h
	int 21h
code ends
end start

这里的:

mov al,a[si]
add b,ax

等价于:

mov al,ds:0[si]
add ds:8,ax

这是因为:

1、assume语句让data段与ds寄存器联系在了一起

2、ds中存放了data段的程序入口

也就是说在使用数据标号的时候要注意段地址关联到哪一个寄存器。

有了这种关联关系的设置,数据标号可以在其他段引用,带冒号的地址标号不能在其他段使用。

直接定址表

通过依据数据,直接计算出所要找的元素的位置的表,称为直接定址表(本质上还是数字标号的应用)。

如果我们要制作一个程序,希望将一个字节放在al中,在屏幕上显示该数字对应的十六进制值,这个问题就非常适合通过简单的映射关系来解决:

showbyte:	jmp short show
		table db '0123456789ABCDEF'					字符表
			
	show:	push bx
		push es
			
		mov ah,al							al和ah存放了数字
		shr ah,1
		shr ah,1
		shr ah,1
		shr ah,1
		and al,00001111b					        al存低4位,ah存高4位
			
		mov bl,al
		mov bh,0							组合成bx
		mov al,table[bx]						通过映射得到对应字符
			
		mov es:[160*12+40*2],ah						显示字符
			
		mov bl,al
		mov bh,0							组合成bx
		mov al,table[bx]						通过映射得到对应字符
			
		mov es:[160*12+40*2+2],al					显示字符
			
		pop es
		pop bx
		ret

如给数字2Bh,拆分成高4位2和低4位11,通过十六进制转换为2Bh。

利用表我们在两个数据集合之间建立一种映射关系,快速得到对应数据,程序简洁、转换速度快、易于扩充。

程序入口地址的直接定址表

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

我们要实现一个程序,用ah寄存器来传递功能号,0、1、2、3代表不同的功能号,对应不同的功能:

setscreen:	jmp short set
	         table dw sub1 sub2 sub3 sub4			        创建字符表
	 set:	push bx
	 
	 	cmp ah,3						如果ah大于3就直接跳到sret
	 	ja sret
	 	mov bl,ah
	 	mov bh,0						组成bx寄存器的值
	 	add bx,bx						bx扩大一倍
	 		
	 	call word ptr table[bx]					调用对应功能的子程序
	 		
	 sret:	pop bx
	 	ret

这里功能号乘2等于地址表对应位置的偏移量。

然后就设置4个sub的子程序即可。

通过这种方式调用子程序易于扩展、调用简单。

posted @ 2020-04-30 22:47  勇闯8  阅读(374)  评论(0编辑  收藏  举报