2011-09-12 8 views
18

ちょうどx64アセンブリの学習を始めました。関数、引数、スタックに関する質問があります。私が理解する限り、関数の最初の4つの引数は、Windowsではrcx、rdx、r8、およびr9レジスタ(およびfloatの場合はxmm0-xmm3)に渡されます。私はdocumentation that mentions this渡って来ている引数が4つ未満の関数に必要なスタック領域を予約していますか?

add: 
    mov r10, rcx 
    add r10, rdx 
    add r10, r8 
    add r10, r9 
    mov rax, r10 
    ret 

しかし、::だから些細な追加機能4つのパラメータで次のようになります

最低でも、各機能は、32バイト(4を予約する必要があります64ビット値)をスタックに格納します。このスペースにより、関数に渡されたレジスタを、よく知られたスタック位置に簡単にコピーすることができます。 呼び出し元関数は、入力レジスタparamsをスタックに流す必要はありませんが、スタック領域の予約によって、必要に応じて確保できます。

私が作っている関数が4つ以下の引数をとってもスタック空間を確保しなければならないのか、それともちょっとお勧めですか?

+1

http://www.agner.org/:インスタンスのGetAsyncKeyStateの最初の2つの命令は、あなたがパラメータに使用する呼び出し先のために確保することになっているの0x20バイト領域での戻り値以上のスタックを上書きoptimize/optimizing_assembly.pdfの第4章には、スペースを確保する必要があることを示すような例があります。 – user786653

+1

編集に時間がかかりません。 [oldnewthing](http://blogs.msdn.com/b/oldnewthing/archive/2004/01/14/58579.aspx)amd64呼び出し規約のブログエントリ。 – user786653

+0

あなたのためのもう一つのパズル:あなたは***リーフ機能***を持っています、それは他の機能を呼び出さないことを意味します。 – jww

答えて

13

あなたの見積もりは、ドキュメントの「呼び出し規約」の部分です。少なくとも、アセンブリコードから他の関数​​を呼び出さなければ、これについて心配する必要はありません。そうした場合は、とりわけ「赤いゾーン」とスタックの配置に関する考慮事項を尊重しなければなりません。

EDIT:this postは、 "赤いゾーン"と "シャドウスペース"の違いを明確にしています。

+0

System Vドキュメントでは「赤いゾーン」が使われていますが、Windowsのドキュメントでは「シャドウスペース」が使用されています。これらは同じですか?誰も知らないなら、私は別の質問で尋ねます。 –

+0

部分的に自分自身に答える:いいえ、 "赤いゾーン"と "シャドウスペース"は同じものではありません。 "Shadow space"は、スタック上に予約された32バイトの名前です。それは呼び出し元によって予約されているので、通常のABIで関数を呼び出し可能にしたい場合はオプションではありませんが、心配する必要はありません。 –

+0

だから私は上記のコードサンプルを "適切"にするためには、最初に 'sub rsp、32'を追加し、最後に 'rsp、32'を追加するのが正しいでしょうか? – Don

0

私はこれを知りませんでしたが、それは事実であるようです。

user32.GetAsyncKeyState - mov [rsp+08],rbx 
user32.GetAsyncKeyState+5- mov [rsp+10],rsi 
user32.GetAsyncKeyState+A- push rdi 
user32.GetAsyncKeyState+B- sub rsp,20 
関連する問題