使用直接定址表遇到的问题

来源:互联网 发布:网络侦探 七只 编辑:程序博客网 时间:2024/05/16 08:49

直接定址表是否要先定义后使用?看起来是的。否则出现错误:



此错误为遍历出错,masm在两次扫描代码时得到的某个标记的地址值不同。


因为在定义直接定址表前就使用了它。修改后没问题。


附代码:

assume cs:codecode segment   start:mov ax,0         mov es,ax         mov di,200h         mov ax,cs         mov ds,ax         mov si,offset int7ch         mov ax,offset sub1 - offset int7ch         add ax,200h         mov [si+2],ax         mov ax,offset sub2 - offset int7ch         add ax,200h         mov [si+4],ax         mov ax,offset sub3 - offset int7ch         add ax,200h         mov [si+6],ax         mov ax,offset sub4 - offset int7ch         add ax,200h         mov [si+8],ax         mov cx,offset int7ch_e - offset int7ch         cld         rep movsb         mov ax,200h         mov es:[7ch*4],ax         mov ax,0         mov es:[7ch*4+2],ax         mov ax,4c00h         int 21h  int7ch:jmp short begin         dw 0,0,0,0   begin:push bx         push ds         mov bx,cs         mov ds,bx         mov bl,ah         mov bh,0         add bx,bx         call word ptr [bx].202h         pop ds         pop bx         iret    sub1:push bx         push cx         push es         mov bx,0b800h         mov es,bx         mov bx,0         mov cx,2000      s1:mov byte ptr es:[bx],' '         add bx,2         loop s1         pop es         pop cx         pop bx         ret    sub2:push bx         push cx         push es         mov bx,0b800h         mov es,bx         mov bx,1         mov cx,2000      s2:and byte ptr es:[bx],11111000b         or byte ptr es:[bx],al         add bx,2         loop s2         pop es         pop cx         pop bx         ret    sub3:push bx         push cx         push es         mov cl,4         shl al,cl         mov bx,0b800h         mov es,bx         mov bx,1         mov cx,2000      s3:and byte ptr es:[bx],10001111b         or byte ptr es:[bx],al         add bx,2         loop s3         pop es         pop cx         pop bx         ret    sub4:push bx         push cx         push es         push si         mov bx,0b800h         mov es,bx         mov cx,24         mov bx,0     s44:push cx         mov cx,80         mov si,0      s4:push es:[bx].160[si]         pop es:[bx][si]         add si,2         loop s4         pop cx         add bx,160         loop s44         pop si         pop es         pop cx         pop bx         retint7ch_e:nopcode endsend start


其中修改部分为:

         mov ax,offset sub1 - offset int7ch         add ax,200h         mov [si+2],ax         mov ax,offset sub2 - offset int7ch         add ax,200h         mov [si+4],ax         mov ax,offset sub3 - offset int7ch         add ax,200h         mov [si+6],ax         mov ax,offset sub4 - offset int7ch         add ax,200h         mov [si+8],ax


原先想通过直接引用直接定址表对其中的数据进行访问。

       
         mov ax,offset sub1 - offset int7ch         add ax,200h         mov table[0],ax         mov ax,offset sub2 - offset int7ch         add ax,200h         mov table[1],ax         mov ax,offset sub3 - offset int7ch         add ax,200h         mov table[2],ax         mov ax,offset sub4 - offset int7ch         add ax,200h         mov table[3],ax

还有一个比较严重的问题:此程序为中断处理程序的安装程序,在用MASM进行编译链接的时候,table标记被解释为table在此安装程序内的偏移,为004E

因此,中断处理程序中对table的引用都是004E 。比如

call byte ptr table[bx]

比如要使用7ch中断中的0号程序,则bx=0 .而table[bx]得到的内存单元是(bx)+004e 并不是我们想要的在中断处理程序中的table值加上偏移量bx定位到的存储子程序IP的内存区。因为table值翻译成二进制代码在编译和链接后就完成了,安装程序只是把代码复制到目的区域。安装完成后0:200处代码如下



红色部分,可以看到call指令使用的寻址call table[bx]代码为call [BX+004E] 。而再看看原安装程序内的情况:



紧接着jmp指令的一条指令,其实不是指令,而是我们定义的四个word型数据。刚好它的偏移地址是004e 也是table标记的地址值。


修改方法是使用数据段的寻址

int7ch:jmp short begin         dw 0,0,0,0   begin:push bx         push ds         mov bx,cs         mov ds,bx         mov bl,ah         mov bh,0         add bx,bx         call word ptr [bx].202h         pop ds         pop bx         iret


不使用table了,但是仍然是直接定址表的思想,程序的地址放在一个连续的空间存放。

使用直接定址表主要的问题:call指令目标地址的定位问题。

1.首先是转移目的地址的存储。本来是用一个 table dw 0,0,0,0存储,但是table在编译连接后获得的是在安装程序中的地址,在中断处理程序中是无效的。

2.后来根据传送来的子程序号用call指令定位子程序IP。搞清楚子程序IP到底存储在什么位置


	
				
		
原创粉丝点击