一个有意思的汇编程序 ——其实就是一个根据位移进行转移的应用=_=

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 ,然后就结束了!

有没有很有趣~~

comments powered by Disqus