5

x86 アーキテクチャで関数呼び出し中に戻りアドレスがスタックにプッシュされない状況はありますか?

4

1 に答える 1

11

いいえCALL、定義により、ターゲットアドレスにジャンプする前にリターンアドレスをスタックにプッシュします。その戻りアドレスはEIP(またはRIP) + sizeof(call instruction)(通常は 5 バイト) です。

インテル® 64 および IA-32 アーキテクチャー・ソフトウェア開発者マニュアルの第 2 巻には、次のように記載されていCALLます。

プロシージャのリンク情報をスタックに退避し、ターゲットオペランドで指定された呼び出し先プロシージャに分岐します。

これも:

  • Near Call — 「現在のコード セグメント内のプロシージャへの呼び出し」。EIP がスタックにプッシュされます。
  • Far Call — 「現在のコード セグメントとは異なるセグメントにあるプロシージャへの呼び出し」。CS、EIP がスタックにプッシュされます。

リターン アドレスをプッシュしない代替手段は、JMP.

私がよく知っているすべての C コンパイラは、命令を使用して x86 で常に関数呼び出しを実装しますが、例外CALL1 つあります。これは特に、ある関数が別の関数呼び出しの結果を返す場合に発生します。例えばJMP

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
}
于 2015-11-13T02:54:28.683 に答える