• 汇编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的子程序即可。

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

  • 相关阅读:
    Day4 0708
    Day2 0706
    两道递推公式题的解题报告
    博客还需优化
    飞行路线Luogu4568
    堆优化Dijkstra(Luogu 4779)
    2019四等奖的清明节征文
    2019四等奖的叶圣陶初稿
    Luogu P1072 Hankson的趣味题
    Loj10022 埃及分数(迭代加深搜索IDDFS)
  • 原文地址:https://www.cnblogs.com/yinyunmoyi/p/12811623.html
Copyright © 2020-2023  润新知