7

当我试图弄清楚某个函数是如何工作的时,我正在查看 IDA 中的一个程序,当我遇到这样的事情时:

; C_TestClass::Foo(void)
__text:00000000 __ZN14C_TestClass7FooEv proc near
__text:00000000                 jmp     __ZN14C_TestClass20Barr ; C_TestClass::Barr(void)
__text:00000000 __ZN14C_TestClass7FooEv endp
__text:00000000

谁能向我解释在这种情况下跳转到一个函数究竟会做什么?我猜它充当其他功能的包装器?

4

2 回答 2

5

您是正确的,跳转通常是一种有效处理未内联的包装函数的方法。

通常,您必须先读取所有函数参数并将它们推回堆栈,然后才能调用子函数。

但是当包装函数具有完全相同的原型时:

  1. 相同的调用约定
  2. 相同的参数(并且以相同的顺序)
  3. 相同的返回类型

不需要所有通常的函数调用开销。你可以直接跳到目标。(这些类别可能不是完全必要的,因为在其他一些情况下仍然可能。)

在调用包装函数时设置的所有参数(在堆栈或寄存器上)都已经为子函数准备好了(并且兼容)。

于 2012-11-24T22:33:53.297 回答
3

这就是所谓的tail-call。编译器能够直接调用该函数并让它返回给原始调用者而不会造成任何问题。例如:

int f(int x)
{
    ...
    return g(y);
}

编译器可以简单地jmp g在最后,因为在与 ' 的参数相同的位置有参数的空间,f并且在返回到f' 的调用者之前不会修改返回值。

于 2012-11-24T22:34:48.177 回答