实验 8 分析一个奇怪的程序
判断下面程序是否可以正确返回,并分析原因。
assume cs:codesg
codesg segment
mov ax,4c00h
int 21h
start: mov ax,0
s: nop
nop
mov di,offset s
mov si,offset s2
mov ax,cs:[si]
mov cs:[di],ax
s0: jmp short s
s1: mov ax,0
int 21h
mov ax,0
s2: jmp short s1
nop
codesg ends
end start
上述程序可以正确返回。分析如下:
1. s0 标号处指令“jmp short s”,将会跳至 s 标号处执行指令。
2. 首次执行 s 标号处的指令后会将 s 地址内存单元所存储的数据,由原来存储着 s 标号处指令 nop 的机器码(代表空指令,一个空指令占用一个字节内存空间,这里包含两个空指令)改变为存储 s2 标号处的指令机器码 EBF6;于是 s 标号处原来的两个 nop 指令机器码变为“EBF6”。该机器码的含义是,向前转移的位移等于标号 s1 与 s2 之间的距离。而标号 s 地址向前转移至这个位移的地址,恰好是 codesg 段的起始地址,该地址的指令是“mov ax,4c00h”和“int 21h”,所以程序能够正确返回。
也就是说,s 标号处原来的两个 nop 指令将被下面的指令取代:
jmp short <codesg 段的起始地址>
也就是:
jmp short cs:[0]
注意,s1 标号处 3 条指令的机器码长度与 s 标号前的 3 条指令机器码长度相同(占用的内存空间大小相同),这就是 s 标号地址所存储的 nop 指令被机器码“EBF6”取代后生成“jmp short cs:[0]”指令的原因所在,即这两对 3 条指令的长度相同导致在相同的转移距离位移的情况下,s 标号处的机器指令“EBF6”执行后会跳至 IP=0(cs:0)处执行指令:
mov ax,4c00h
int 21h
因此程序可以正确返回。