x86 - CALL指令是否始终将EIP指向的地址推送到堆栈?

时间:2015-11-13 02:50:10

标签: assembly x86 call

在x86架构的函数调用期间,是否存在返回地址未被压入堆栈的情况?

1 个答案:

答案 0 :(得分:10)

没有。根据定义,CALL将在返回目标地址之前将返回地址压入堆栈。返回地址为EIP(或RIP)+ sizeof(call instruction)(通常为5个字节。)

Volume 2 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual说明CALL

  

保存将堆栈和分支上的信息链接到使用目标指定的被调用过程的过程   操作数。

这包括:

  • 近呼叫 - “调用当前代码段中的过程”,其中EIP被压入堆栈。
  • 远程调用 - “调用位于与当前代码段不同的段中的过程”,其中CS,EIP被压入堆栈。

替代方法,而不是推送返回地址,是JMP

我熟悉的每个C编译器总是使用CALL指令在x86上实现函数调用,但有一个例外:tail call,可以用JMP实现。当一个函数返回另一个函数调用的结果时,会发生这种情况。 E.g。

int bar(int a, int b);

int foo(int a, int b)
{
    if (a < b)
       return 0;

    return bar(a, b);   // Will probably be:    jmp  bar
}