实验8 分析一个奇怪的程序
分析下面的程序,在运行前思考:这个程序可以正确返回吗?
运行后再思考:为什么是这种结果
通过这个程序加深对相关内容的理解。
assume cs:code
code 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
code ends
end start
经过运行,发现过程是这样的:
1. mov ax, 0
2. s: nop
nop
3. mov di, offset s
mov si, offset s2
mov ax, cs:[si]
mov cs:[di], ax ;将s2的代码给了s
4. jmp short s ;跳到s
5. jmp short s1 ;在s的位置执行了s2的命令,向前10个字节,一下子跳到 mov ax 4c00h去了
6. mov ax, 4c00h
为什么会出现这种情况?是因为在编译时,jmp short 命令编译器已经确定好了位移的长度。
第一个jmp对应
s0: jmp short s
根据机器码可知EBF0,它的位移是补码F0,也就是11110000,最高位是1,所以是负数,其正数应该是00010000h= 16。
负数的补码和正数的补码相互转换——从右向左复制,复制完一个1, 后面全部取反即可
所以为-16。可以验证一下,jmp后一位为0018h,s为0008h,0008h - 0018h = 8 - 24 = -16。
第二个jmp对应
s2: jmp short s1
机器码F6,也就是-10,验证,0018h - 0022h = 24 - 34 = -10,本身这个-10,是从s1到s2的。
mov di, offset s
mov si, offset s2
mov ax, cs:[si]
mov cs:[di], ax
这段代码将s2给了s。等到跳到s后,就执行了原先那个s2的命令。
jmp short s1 ;向前10字节
在s处IP=8,减掉10就是0(不能小于0)。