x86_64 のデフォルトの呼び出し規約が変更され、スタックを使用するだけでなく、レジスタを使用してパラメーターを渡すようになりました。
通過
引数が分類されると、レジスタは次のように渡すために (左から右の順序で) 割り当てられます。
- クラスが MEMORY の場合、引数をスタックに渡します。
- クラスが INTEGER の場合、シーケンス %rdi、%rsi、%rdx、%rcx、%r8、および %r9 の次に使用可能なレジスタが使用されます *
- クラスが SSE の場合、次に使用可能な SSE レジスターが使用され、レジスターは %xmm0 から %xmm7 の順序で取得されます。
...
*%r11 は保持する必要もなく、引数を渡すためにも使用されないことに注意してください。このレジスタをスクラッチ レジスタとして使用できるようにするということは、制御を転送する必要があるアドレスを計算するときに、PLT 内のコードがレジスタをスピルする必要がないことを意味します。%raxis は、可変数の引数を必要とする関数に渡される SSE 引数の数を示すために使用されます。%r10 は、関数の静的チェーン ポインターを渡すために使用されます。
スタックに直接プッシュするのではなく、文字列と整数値をそれぞれ %rdi レジスタと %rsi レジスタに渡したい場合があります。
mov $213, %esi ;%d is not a 64-bit integer
mov $ssttrr, %rdi
mov $0, %rax ;no sse registers as arguments
call printf