千哥读书笔记:汇编语言(王爽第四版)第9章 实验八

前几天,千哥在发表了《千哥读书笔记:汇编语言(王爽第四版)第8章实验七》以后,又有朋友问,汇编语言(王爽第四版)第9章 实验八,完全搞不懂。下面,千哥再来逐一解析。

实验八:

分析下面的程序,在运行前思考,这个程序可以正确返回吗?

先来看完整的代码:

=========这是代码与内容的分割线==========

assume cs:codesg

codesg segment

mov ax,4c00h

int 21h

start: mov ax,4

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

=========这是代码与内容的分割线==========

图片

编译成p9108.exe,在DEBUG下调试,程序入口在076a:0005处,用 u 076a:0005观察:

图片

从076A:0008至076A:0009处,可以观察到定义了两个nop(机器码90 90)

然后执行:

mov di,offset s

mov si,offset s2

可以看出,offset s的偏移量是0008,offset s2的偏移量是0020,分别赋值给di和si,接下来,执行:

mov ax,cs:[si]

mov cs:[di],ax

也就是说,将 076A:0020的内容,赋值给AX,AX再将这个内容,赋值给076A:0008。那么, 076A:0020的内容是多少呢?看下图:

图片

076A:0020的机器码是EBF6,对应的指令是JMP 0018。也就是说,在执行mov cs:[di],ax时,要将EBF6这个机器码,传送到076A:0008至076A:0009这两个节字的内存单元。

在执行完上面这些指令以后:

图片

下一条指令,就是JMP 0008,也就是即将执行jmp short s,也就是将执行传送到076A:0008里的EBF6。在这里,魔法就出来了:

我们在前面知道,076A:0020的机器码是EBF6,对应的指令是JMP 0018,而076A:0018后面对应的指令是:

s1:mov ax,0

int 21h

mov ax,0

在S1这个位置,就是076A:0018,因为这段代码:s2:jmp short s1 所在的位置,就是076A:0020,显示的指令就是JMP 0018,现在就是要执行从076A:0018开始的代码,也就是 mov ax,0

当执行了mov ax,0以后, int 21H会从AX中获取返回码,此时是0。所以,复制在076A:0008至076A:0009处的机器码EBF6,应对的指令,就不再是JMP 0018,而变成了 JMP 0000:

图片

大家可以看到,0076A:0020 处的机器码是EBF6,对应的指令明明是 JMP 0018;而在把这个机器码EBF6复制到0076A:0008以后,对应的指令却变成了JMP 0000。说明在复制的过程中,是执行过mov ax,0和 int 21h的。

而在执行 JMP 0000,就跳转到mov ax,4c00h:

图片

最后再执行 int 21h:

图片

AX被设为4C00H,int 21H从AX中获取返回码,程序正常结束。程序正确返回,打完收工。

这个程序主要探究的是int 21H的作⽤。其中的奥妙在于:

1、jmp short 标号,这个指令,并不显示绝对地址,标号所反映的,只是计算偏移量的相对地址,所以 JMP 0018和 JMP 0000显示的机器码都是F6EB

2、int 21H会自动从AX获取返回码,并决定程序是否能够正确返回。

3、机器在执行相应命令的时候,会自动生成中间变量,但这些中间变量不会在debug中显示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值