前言
本文是学习王爽老师《汇编语言》(第四版)第九章 实验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.初始时指令存储情况
在debug中运行前,使用U命令查看指令以及对应的十六进制数据,结果如下。
下面以表格的形式进行整理。
标号 | IP(偏移地址) | 数据形式 | 指令形式 | 备注 |
---|---|---|---|---|
0000 | B8004C | mov ax,4c00H | ||
0003 | CD21 | int 21H | ||
start | 0005 | B80000 | mov ax,0000 | |
s | 0008 | 90 | nop | |
0009 | 90 | nop | ||
000A | BF0800 | mov di,0008 | ||
000D | BE2000 | mov si,0020 | ||
0010 | 2E | cs: | ||
0011 | 8B04 | mov ax,[si] | ||
0013 | 2E | cs: | ||
0014 | 8905 | mov [di],ax | ||
s0 | 0016 | EBF0 | jmp 0008 | 跳转程序,位移为F0H(反码) |
s1 | 0018 | B80000 | mov ax,0000 | |
001B | CD21 | int 21H | ||
001D | B80000 | mov ax,0000 | ||
s2 | 0020 | EBF6 | jmp 0018 | 跳转程序,位移为F6H(反码) |
0022 | 90 | nop |
下面分析这些指令。
0016H处的指令,是jmp跳转指令。 当前jmp指令的偏移地址是0016H,下一条指令的偏移地址是0018H,而要跳转到的标号s的偏移地址是0008H。“jmp short 标号”指令中存储的应当是地址的位移,而不是目标地址。因而位移是 0008H - 0018H = -0010H = -16(十进制)。
由于计算机使用反码表示数字,于是就将-0010H转为反码。根据反码规则,10H的二进制为0001 0000 B,取反加一得 1111 0000 B,即F0H,这就是-0010H的反码。因而内存中的数据为“EBF0”,其中“EB表示跳转”,“F0”就是要跳转的16进制位移量。
同理,0020处的指令,位移量应当是 0018H - 0022H = -000AH ,用反码表示为 F6 H。因此此处的数据为“EBF6”,即跳转程序且位移量为F6H(反码)。
2.运行时指令存储情况
下面以表格形式逐条分析指令。
关键点在于,要理解0020H处的指令,并不是“跳转到0018H处”,而是“跳转程序,位移量为F6H”。
标号 | IP(偏移地址) | 数据形式 | 指令形式 | 备注 |
---|---|---|---|---|
start | 0005 | B80000 | mov ax,0000 | ax=0 |
s | 0008 | 90 | nop | 这两个字节之后会被改写为EBF6H, 即跳转程序,转移位移为F6H (-000AH的反码) |
0009 | 90 | nop | ||
000A | BF0800 | mov di,0008 | di=8H | |
000D | BE2000 | mov si,0020 | si=20H | |
0010 | 2E | cs: | ||
0011 | 8B04 | mov ax,[si] | ax=cs:[20H]=EBF6H | |
0013 | 2E | cs: | ||
0014 | 8905 | mov [di],ax | cs:[8H]=EBF6H | |
s0 | 0016 | EBF0 | jmp 0008 | 当前IP=0018H,指令为 跳转程序,位移为F0H(-10H的反码), 即跳转至08H处执行 |
s | 0008 | EBF6 | jmp | 当前IP=10H,指令为跳转程序,位移为 F6H(-000AH的反码),即跳转至 00H处执行 |
0000 | B8004C | mov ax,4c00H | 程序返回 | |
0003 | CD21 | int 21H |
因此,最终程序能够正确返回。
总结
本文分析了 王爽老师《汇编语言》(第四版)第九章 实验8 的程序原理,加深了对于jmp指令的参数为“位移量”而不是“目标地址”的理解。