实验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
解析
顺序执行
第 4、5 行:退出程序:首先退出指令在程序插入 strart
的前面,说明肯在某一步能跳上来,才可以正常退程序。
从第 7 行开始逐步执行。
第 11、12 行:分别拿到 s
和 s2
的地址。
第 13、14 行:把 s2
的指令复制到 s
处。
考点: jmp short s1
是短跳转,短跳是相对移动。
相对跳转多少字节是编译时已经算好的。
所以这里的机器码含义就是向上偏移 10 字节。
当这句被移到 s
后,此时再执行它 向上偏移 10字节
就来到了 第 4 行
。
因此,程序可以正常执行退出。
查看反汇编
在 debug 中可以看到
jmp short s1
在 076C:0020
机器码是 EBF6
其中 EB
对应 JMP
,F6
就对应偏移量了。
我们已知系统中保存数据是补码形式。所以我们来把 F6
转原码看一下。
步骤 | 结果 | 说明 |
---|---|---|
转二进制 | 1111 0110 | 8421 = F, 0110=6 |
减1得反码 | 1111 0101 | |
取反得原码 | 1000 1010 | 有符号数,符号位不动 |
转10进制 | -10 |
测试一下
我们做个实验,直接修改 076C:0020
机器码为 EBF4
。
parseInt( "0xF4", 16) << 24 >> 24; // F4 = -12
这时可以看到反汇编代码中 JMP
跳转的地址变成了 0016