一个有意思的汇编程序 ——其实就是一个根据位移进行转移的应用=_=
October 6, 2013
masm
分析一下这个程序=_=
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
开始,一眼看去,这个程序应该会陷入死循环吧。。
其实,认真分析之后就会发现。这个程序竟然可以正常地运行并且退出!
首先,一定要注意jmp指令的内部运行方法!
首先呢,为了方便,我们先记录下每个标号的偏移地址和机器码。方便以后分析。
S: CS:8H
CS:9H
S0: CS:16H EBF0 JMP 8
S1: CS:18H B80000
S2: CS:20H EBF6 JMP 18
之后,S处的数据发生改变:
S: CS:8H EBF6
S0: CS:16H EBF0 JMP 8
S1: CS:18H B80000
S2: CS:20H EBF6 JMP 18
然后,在标号S0处,代码回到S处,这里,S处已经有代码了。所以会执行机器码EBF6,这是什么意思呢?这实际上是一个jump语句,只是不是jump short s1了,因为拷贝的是机器码,而机器码记录的是位移,也就是说,还记得吗?jmp是根据位移进行转移的,F6是-10的补码形式,所以会让IP-10个字节,注意,执行这条语句的时候,IP=IP+2-10=0.这里,为什么要+2呢?因为根据位移进行转移的时候,IP是指向jmp后面的指令的,而jmp指令的大小是2个字节,所以要+2,,使得IP指向下一条指令。所以,程序又欢乐地回到开始了,正好执行mov ax, 4c00h int 21h ,然后就结束了!
有没有很有趣~~