2016-08-20 4 views
1

私はスタックフレームを追跡するためにベースレジスタを使用することは本当に必要ではないということを読んでいます。私はどのようにコンパイラがこれを達成しているのかわからない、スタックフレームのサイズをどこかに格納して読んで、それを%rspに追加するのだろうか?限り、あなたは2例のいずれかにいるように、いずれかの通常必要はありません%rbpレジスタなしでスタックフレームの割り当て解除はどのように行われますか?

+2

コンパイラは、%rbpのスタックフレームを、C99の可変長配列やそのようなものを含む関数で作成します。フレームサイズがコンパイル時定数である場合、スタックフレームは必要ありません。この場合、それは 'add 'への即値オペランドとしてのみ格納されます。任意のコンパイラ出力を見てください。 http://gcc.godbolt.org/にあります。スタックフレームサイズは '.eh_frame'メタデータにも格納され、例外ハンドラ(およびデバッガ)がスタックを巻き戻すことができます。 –

答えて

5

  • rspが全く変更されません既知の量によってのみ変更される

    1. rsp(あなたができましたたとえば、これは既知の量であり、その量は0)

  • は、典型的にはx64のコードで、 rspのみプロローグ、エピローグで変更、および暗黙的コール/リターンです。任意の一時的なスペースは、先頭から割り当てられ、スタックフレームへのインデックス付けによってアドレス指定されます(オフセットは基本ポインタの代わりに rspからですが、 rspが変更されない場合は変更されません)。ポップス。その場合、古い rspを復元するのは簡単です。プロローグで減算したのと同じものを追加するだけです。

    これは特に、redzoneがあるところのLinuxに当てはまります。多くのリーフ関数では、rspをまったく変更しないで取り除くことができます。この場合、プロローグやエピローグは必要ないかもしれません。ちょうどretが続く通常のコードがたくさんあります。

    明らかにalloca(および可変量のスタック領域を割り当てる他の構造体)はこれを破り、フレームポインタが再び使用されます。

    関連する問題