2012-11-24 14 views
7

私はこのようなものに出くわしたとき、私は、特定の機能が働いていた方法を把握しようとしていたとして、私はIDAでプログラムを見ていた:関数アドレスでJMPを使用すると、どのような影響がありますか?

; 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 

誰もが正確に機能するだろうジャンプものを私に説明できますこのような場合は? 私はそれが他の関数のラッパーとして機能すると推測していますか?

答えて

5

ジャンプが、インライン化されていないラッパー関数を効率的に処理する方法であることは間違いありません。

通常、サブ関数を呼び出す前に、すべての関数パラメータを読み込んでスタックに戻す必要があります。

しかし、ラッパー関数はまったく同じプロトタイプがある場合:

  1. 同じ呼び出し規約
  2. 同じパラメータ(と同じ順序で)
  3. 同じ戻り値の型

をなしがありますすべての通常の関数呼び出しオーバーヘッドが必要です。ターゲットに直接ジャンプすることができます。

ラッパー関数を呼び出すときにセットアップされたすべてのパラメーター(スタックまたはレジスターのいずれか)は、すでにその場に置かれています(これらのカテゴリーは完全には必要ではないかもしれません。互換性があります)。

3

これはテールコールとして知られています。コンパイラは直接関数を呼び出すことができます。は元の呼び出し元に問題なく戻ります。たとえば:

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

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

関連する問題