汇编语言跳转指令《汇编语⾔》实验8
⼀个奇怪的程序
分析下⾯的程序,在运⾏前思考:这个程序可以正确返回吗?
运⾏后再思考:为什么是这种结果?
通过这个程序加深对相关内容的理解。
assume cs:codesg
codesg segment
mov ax,4c00h
int21h
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
int21h
mov ax,0
s2:
jmp short s1
nop
codesg ends
end start
在运⾏前,单看这个程序,我个⼈觉得是不能够正确返回的,因为他把返回的标识放到了代码段的开头,却没有给出跳转到该标识的⽅式。然后试着运⾏⼀下:
居然成功返回了。
为什么是这种结果呢?我们可以Debug⼀下。
我们⾸先单步执⾏程序两次,执⾏的是前⾯两条nop指令,该指令不会产⽣任何的效果,只会消耗两个始终周期。但是有⼀个值得我们注意的地⽅是:执⾏第⼀条nop指令的时候,CS的值为076A,IP的值为0008。也就是说,我们将结束的标识成功的写⼊了代码段的前8个字节中。
接下来这两条指令分别把标志s和标志s2的偏移值写⼊了di和si。
由上图我们可以知道,紧接着的两条指令的作⽤是把s2标志处的那条跳转指令复制到了s处,所以此时s标志处不再是nop指令,⽽是jmp short s1。根据程序,我们下⼀条指令会跳转到s标志处,也就是JMP 0008,(0008是s的偏移值)。
我们执⾏跳转到s标志的指令之后,系统提⽰我们,下⼀条指令是跳转到0000处,为什么会这样呢?按道理我们这⾥是把s2标志处的跳转指令给复制过来了,根据复制过来的跳转指令,我们应该是跳到s1处才对,为什么会跳到0000处呢?
根据之前学到的知识可以解释。像jmp,jcxz,loop等指令,它们在执⾏时会对IP进⾏修改,但是它们对IP的修改是根据转移⽬的地址和转移起始地址之间的位移来进⾏的。在s2标志处的那条指令,它的作⽤就是把IP往回修改8个单位(因为s1和s2之间的位移是8)。所以将这条指令复制到s处,在执⾏时,它也会往回修改8个单位,从⽽跳转到我们⼀开始定义的结束语句,结束程序。
这就解释了为什么我们没有在定义的结束语句那⾥设置标志,但依然能够跳转到结束语句并结束程序的。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。