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
from 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
this case corresponds to the format just to assembly code, seen disassembled when confusion may sometimes occur format
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:
The tangled bug me so long to finally solve the problem of address !!!