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

これは末尾呼び出しとして知られているものです。コンパイラーは、関数を直接呼び出して、問題を発生させることなく元の呼び出し元に戻すことができます。例えば:

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

jmp gの引数と同じ場所に引数の余地があり、呼び出し元fに戻る前に戻り値が変更されないため、コンパイラは単純に最後にできます。f

于 2012-11-24T22:34:48.177 に答える