8

gcc -Sメモリとスタックがどのように機能するかを理解するために遊んでいます。これらのプレイ中に、私にはいくつかの不明な点が見つかりました。理由を理解するのを手伝ってもらえますか?

  1. 関数を呼び出すと、呼び出された関数の引数が設定され、代わりに使用movされます。使わないメリットは?esppushpush

  2. スタックに配置された引数で動作する関数は、それらを次のように指しますebp + (N + offset)(Nは戻りアドレス用に予約されたサイズです)。esp - offsetどちらがより理解しやすいかを期待しています。どこでも基本的なポイントとして使用する理由は何ebpですか? これらが等しいことは知っていますが、とにかく?

  3. の冒頭にあるこの魔法は何のためmainですか? なぜespこの方法でのみ初期化する必要があるのですか?

    and    esp,0xfffffff0
    

ありがとう、

4

1 に答える 1

7

64 ビット環境では引数がレジスターで渡されるため、32 ビット環境で作業していると仮定します。

質問1

おそらく、ここで浮動小数点引数を渡しています。push32 ビット ランタイムの命令は一度に 4 バイトをプッシュするため、値を分割する必要があるため、これらを直接プッシュすることはできません。から 8 を引きesp、8 バイトのクワッドワードを に移動する方が簡単な場合があります[esp]

質問2

ebpは、32 ビット コードのスタック フレーム内のパラメーターとローカルをインデックス化するためによく使用されます。これにより、スタック ポインターが移動しても、フレーム内のオフセットを固定できます。たとえば、

void f(int x) {
    int a;
    g(x, 5);
}

スタック フレームの内容にesp, then ais atのみでアクセスした場合[esp]、戻りアドレスは at になり、 at[esp+4]xなります[esp+8]。を呼び出すコードを生成しましょうg。最初に 5 を押してから を押す必要がありxます。しかし、5 を押した後、xfromのオフセットespが変更されました! これが使用される理由ebpです。通常、関数への入り口で、 の古い値をプッシュしebpて保存し、次に にコピーespebpます。ebpスタック フレームの内容にアクセスするために使用できるようになりました。引数を渡している途中では動きません。

質問 3

このand命令は、 の最後の 4 ビットをゼロにしてesp、16 バイト境界に揃えます。スタックは下に成長するので、これは安全です。

于 2012-06-24T07:24:51.010 に答える