focus on linux, c/c++, lua

深层理解指令跳转

这段时间看王爽的汇编看的效率很高,看样在学习高级语言后再学习asm是速度比较快。其中有讲到指令跳转的地方,我当时想到的就是goto,用汇编来解释再贴切不过了。我贴上一道习题与讲解,加深印象。

---------------------------------

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

运行后再思考:为什么是这种结果?

通过这个程序加深对相关内容的理解。

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

-------------------------------------------------------------------------------------------------------------------------------------------------------

程序可以正常返回。

 

详细分析:

在此题中较为深入地考察了‘段内直接短转移’[形如:jmp short 标号]的概念。

我们知道程序中:

mov di,offset s

mov si,offset s2

mov ax,cs:[si]

mov cs:[di],ax

四条指令的作用是将标号s2处的一条指令复制到标号s处。这时我们应该关心所复制的语句"jmp short s1"对程序的影响:我们知道在段内直接短转移指令所对应的机器码中,并不包含转移的目的地址,而包含的是转移的位移量(如对此概念还不太熟悉,请查看书中第167页的内容)。也就是说,在源程序的编译过程中,编译器遇到段内直接短转移’[形如:jmp short 标号]时就会自动算出其要跳转的位移量,以便程序在执行段内直接短转移的指令时就根据位移量进行(向前或向后)跳转。通过调试中的U命令我们可以看到指令's2:jmp short s1'所对应的机器码是EBF6F6h(-10d的补码)就是跳转的位移量[此位移量也可由指令's2:jmp short s1'处的偏移地址18h减去指令's2:jmp short s1'后一个字节的偏移地址22h得出]。这时我们就知道了其实复制到标号s处的指令所对应的机器码就是EBF6(刚好取代两个nop所对应的机器码),它的作用就是将当前IP向前移动10个字节。当程序执行标号s0处的指令后,程序便跳到标号s处接着执行标号s处的指令。s处的指令的作用是向前跳10字节,于是便跳到了代码中的第一条指令,继续执行后便实现了程序的正常返回

[注意:此程序不会也不可能执行标号s1处后的指令。]


posted on 2010-10-20 10:15 zuhd 阅读(285) 评论(0)  编辑 收藏 引用 所属分类: my tips


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理