web-dev-qa-db-ja.com

x64アセンブリの「シャドウスペース」とは何ですか?

この影の空間についてたくさんのトピックを見つけましたが、どれにも答えが見つからなかったので、私の質問は次のとおりです。

プロシージャに入る前に、スタックポインタからどれだけ正確に減算する必要がありますか?

そして、「シャドウスペース」を差し引く前に、プロシージャパラメータをスタックにプッシュする必要がありますか?

コードを逆アセンブルしましたが、ロジックが見つかりませんでした。

23
Igor Bezverhi

シャドウスペーススピルスペースまたはホームスペース)は、x64のデバッグを容易にするために使用することを目的としています。

最初の4つのパラメーターはレジスターに渡される であることを思い出してください。デバッガーに侵入して呼び出しスタックでスレッドを検査すると、関数に渡されたパラメーターを確認できなくなります。レジスタに格納されている値は一時的なものであり、コールスタックを上に移動するときに再構築することはできません。

ここでホームスペースが機能します。コンパイラーは、後で検査するためにレジスター値のコピーをスタックに残すために使用できます。デバッガ。これは通常、最適化されていないビルドで発生します。ただし、最適化が有効になっている場合、コンパイラーは通常、ホームスペースをスクラッチで使用できるものとして扱います。スタックにはコピーが残っておらず、クラッシュダンプのデバッグは悪夢になります。

最適化されたx64コードのデバッグの課題 この問題に関する詳細情報を提供します。

28
IInspectable

シャドウスペースは、呼び出されたプロシージャ用に予約する必要がある必須の32バイト(4x8バイト)です。これは、呼び出す前にスタックに32バイトを提供する必要があることを意味します。このスペースは初期化しないでおくことができます、それは問題ではありません。

X64呼び出し規約では、4番目以降の引数は、このシャドウスペースの一番上にあるスタックにプッシュされることに注意してください(32バイトの前にプッシュされます)。

つまり、x64の関数には最低4つの引数があるように見えますが、レジスターの最初の4の値があります。

X64を呼び出すときは、スタックの配置なども考慮する必要があります。

9
ElderBug