王爽汇编语言 一个奇怪的程序

这里写图片描述

先大概分析分析:
程序从 start: mov ax, 0 开始运行,运行到s0时,已经将s处替换成了s2处的 jmp short s1. 而程序编译后,s2处的汇编语句:jmp short s1对应的机器码是:EBF6(F6即-10的补码)。 也就是说,此刻s处对应机器码是EBF6。
然后执行s0:jmp short s,程序跳回s处,此刻s处对应的机器码是EBF6,执行这条指令,IP向上移动10,即指向cs:0000H,也就是mov ax, 4c00H处,然后继续执行,程序正常返回

下面用debug跟踪:
mov ax, 4c00H 076A:0000
int 21H 076A:0003

程序从此处(start:处)开始执行
mov ax, 0 076A:0005 IP = 0005H
nop 076A:0008 IP = 0008H
nop 076A:0009 IP = 0009H
mov di, offset s 076A:000A IP = 000AH
mov si, offset s2 076A:000D IP = 000DH
mov ax, cs:[si] 076A:0010 IP = 0010H
mov cs:[di], ax 076A:0013 IP = 0013H
执行完以上指令时,已经将s2处指令:jmp short s1 拷贝到s处,而s2处对应的机器码是EBF6(下面解释为什么是F6),故此时,076A:0008处的值是EBF6(两个nop指令即跳过两个字节,刚好EBF6也是两个字节)

接下来这样执行:
jmp short s 076A:0016 IP = 0016H
jmp 0008
跳回s处,即076A:0008处,接下来这样执行:
jmp short s1 076A:0008 IP = 0018H
jmp 0000
这里你可能就有疑问了,不是jump 到s1吗,为什么对应 指令是jmp 0000.为什么?因为:
jmp short s1对应的机器码是EBF6(下面解释为什么是F6),所以当程序运行到EBF6(即jmp short s1)时,先将EBF6缓存到指令缓冲区,IP+2(即IP变成000A),然后执行EBF6,而F6是-10的补码,所以IP-10,即IP变成了0000,此时cs:0000刚好指向了mov ax, 4c00H 指令
所以,接下来这样执行
mov ax, 4c00H
int 21H
然后程序正常返回退出

到这里可能你就只剩下一个疑问了,为什么jmp short s1对应的机器码是EBF6呢?
源程序经过编译链接,将汇编指令变成对应的机器码,jmp指令对应的机器码中,EB后面的补码(本处是F6)对应的源码(本处是-10),直接决定了IP的偏移量。
那么为什么是F6,这就要有jmp指令和对应的标识处的位置决定。
s1: mov ax, 0 076A:0018
int 21H 076A:001B
mov ax, 0 076A:001D
s2: jmp short s1 076A:0020
nop 076A:0022

看:0018H - 0022H = -000AH,也就是-10啦!!
至于为什么是0018H - 0022H,里面涉及地址计数器(AC)的知识,若想了解,可以看看本书的附注3

发布了23 篇原创文章 · 获赞 22 · 访问量 2万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章