阅读(3629) (1)

Assembly CALL和RET指令

2016-10-28 14:16:08 更新
80x86提供了两条使用堆栈的指令来使子程序调用变得快速而简单。CALL指令执行一个跳到子程序的无条件跳转,同时将下一条指令的地址推入栈中。RET指令弹出一个地址并跳转到这个地址去执行。使用这些指令的时候,正确处理堆栈以便RET指令能弹出正确的数值是非常重要的!


前面的例子可以使用这些新的指令来重写。把25行到34行改成:


mov       ebx, input1

call        get_int

mov       ebx, input2

call        get_int


同时把子程序get int改成:


get_int:
        call read_int
        mov [ebx], eax
        ret



CALL和RET指令


CALL和RET指令有几个优点:


1、它们很简单!

2、它们使子程序嵌套变得简单。注意:子程序get_int调用了read_int。这个调用将另一个地址压入到堆栈中了。在read_int代码的末尾是一条弹出返回地址的RET指令,通过执行指令重新回到get int代码中去执行。然后,当get int的RET指令被执行时,它弹出跳回到asm main的返回地址。这个之所以能正确运行,是因此堆栈的LIFO特性。


记住弹出压入到堆栈的所有数据是非常重要的。例如,考虑下面的代码:


1   get_int:
2            call read_int
3            mov [ebx], eax
4            ret                   ; 弹出EAX的值,没有返回地址!!

这个代码将不会正确返回!