Assembly language address inquiry

Use call after call to interrupt instruction to use iret instruction to return to the source oh !!!

Source code as follows

assume cs:code
code segment

	start:push cs
		  pop ds
		  
		  mov ax,0
		  mov es,ax
		  
		  mov si,offset setscreen
		  mov di,200h
		  mov cx,offset screenend-setscreen;设置cx为传输长度
		  cld;
		  ;将代码从ds:[si]传送到es:[di]
		  rep movsb
		  
		  mov ax,0
		  mov es,ax
		  mov word ptr es:[7ch*4],200h
		  mov word ptr es:[7ch*4+2],0
		  ;将起始地址放入中断向量中
		  
		  mov ax,4c00h
		  int 21h
		;debug技巧:先运行中断之后再debug
		;测试的t32.exe
	
setscreen:jmp short set
		  
	table dw sub1,sub2,sub3,sub4
	
	set  :push bx
		  
		  cmp ah,3
		  ja sret
		  ;判断功能号是否大于3
		  ;大于3时直接返回
		  
		  mov bl,ah
		  mov bh,0
		  add bx,bx;根据ah中的功能
		  ;计算对应子程序在table表中的
		  ;偏移量
		  ;ip = 0216
		  
		  mov ax,table
		  call word ptr table[bx]
		  ;调用对应的功能子程序
		  
	sret :pop bx
		  ret
   setend:nop
   
     sub1:push bx
		  push cx
		  push es
		  mov bx,0b800h
		  mov es,bx
		  mov cx,2000
		  
	sub1s:mov byte ptr es:[bx],' '
		  add bx,2
		  loop sub1s
		  
		  pop es
		  pop cx
		  pop bx
		  ret
		  
	 sub2:;运行02时应该跳入到
		  ;sub2程序中,但是该程序没有
	      push bx
		  push cx
		  push es
		  
		  mov bx,0b800h
		  mov es,bx
		  mov bx,1
		  mov cx,2000
		  ;定位到显存区域及设置循环次数
		  
	sub2s:and byte ptr es:[bx],11111000b
		  or es:[bx],al
		  add bx,2
		  loop sub2s
		  ;设置第0,1,2位的前景色
		  
		  pop es
		  pop cx
		  pop bx
		  ret
		  
	 sub3:push bx
		  push cx
		  push es
		  ;压栈保存数据
		  
		  mov cl,4
		  mov al,02h
		  shl al,cl
		  mov bx,0b800h
		  mov es,bx
		  mov bx,1
		  mov cx,2000
		  
		  
	sub3s:and byte ptr es:[bx],10001111b
		  or es:[bx],al
		  add bx,2
		  loop sub3s
		  
		  pop es
		  pop cx
		  pop bx
		  ret 
		  ;出栈恢复数据
		  
	 sub4:push cx
		  push si
		  push di
		  push es
		  push ds
		  
		  mov si,0b800h
		  mov es,si
		  mov ds,si
		  mov si,160
		  mov di,0
		  cld
		  mov cx,24
		  ;共复制最后一行
		  
	sub4s:push cx
		  mov cx,160
		  rep movsb
		  pop cx
		  loop sub4s
		  
		  mov cx,80
		  mov si,0
		  
   sub4s1:mov byte ptr [160*24+si],' '
		  add si,2
		  loop sub4s1
		  ;最后一行清空
		  
		  pop ds
		  pop es
		  pop di
		  pop si
		  pop cx
		  ret 
screenend:nop
code ends
end start

At this point view 0000: 0200 part of the contents of the following
Here Insert Picture Descriptionfrom the beginning of the code should be interrupted as follows:

jmp short set

table dw sub1,sub2,sub3,sub4
;0051,0069,0087,00AB

;下面三条对应的机器码:5380,
;03fc,1377,之前使用u命令时翻译错误

;u0000:020a开始翻译指令
set  :push bx
	  
	  cmp ah,3
	  ja sret
	  ;判断功能号是否大于3
	  ;大于3时直接返回

Not fully correspond on, this is due to debug when disassembly of the dislocation
which u0000: 0200 from 0000: 0051,0069,0087,00ab 0202 start of sub1, sub2, sub3, sub4
corresponding offset, while the original disassembly format disrupted
Next we from 0000: 020a start disassembling
Here Insert Picture Description
this case corresponds to the format just to assembly code, seen disassembled when confusion may sometimes occur format
Here Insert Picture Description
table instruction executing the starting position the address 020a jmp, i.e. 0000: 0202
offset is relative to the table in terms of the offset, the address corresponding sub1 0000: 0202 + 51h = 0000: 0253,
from 0000: operation start position 0253 of sub1 Code
however does not address ah? ? ? How to calculate addresses are not right? ? ?
Access to information that
turned out, the program at compile time the compiler has calculated a good address labels shown in the figure: 005F, 007A, 0098,00BA, new interrupt routines when loading and ip reset cs value, but the reference offset address has changed, thus pointing to the wrong location. We can use org directive tells the compiler to recalculate the address label, the changes are as follows:
Here Insert Picture Description
The tangled bug me so long to finally solve the problem of address !!!

Published 17 original articles · won praise 7 · views 2978

Guess you like

Origin blog.csdn.net/znevegiveup1/article/details/103891036