搭建博客以来一直很少更新,从这篇开始会加快更新进度。
以下是对《汇编语言》中的八实验的解析:
代码
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
猜想
通过代码解读:它首先用offset指令取s的地址存在di中,后取s2的地址存在si中通过mov ax,cs[si]与 mov cs:[di],ax
将s2地址的储存单元中的指令搬到了s地址的储存单元中并执行,执行后应该跳到s1处进入死循环。
分析
实际却非如此:
一.先对内存空间进行查看:
二.单步进行输入“t”查看运行
这里jump 0008就是到s的地址,在之前s的内存已经被s2覆盖于是cs ip指向s2代表的代码,于是执行后cs ip指向下一指令也就是0010到0011的数
据储存,将其作为代码执行。
那么问题来了,为什么变成了jmp 0000了?
如图:
因为jmp指令是根据s2到s1的标号偏移量决定的,在还没执行前就已经定好了即决定了偏移量为F6,而F6作为补码
储存,作用为-10,也就是减10个字节。也就从0010减到了0000 也就是开始的代码
mov ax,4c00h
int 21h
最终结束。
总结:jmp并不是随意跳跃的,是在开始就决定好的偏移量,如果如上题转换位置也只会按原来规定的偏移量进行,并不能换到我们目标位置。