Phase 3: C連携 / ABI
このフェーズでは、Cとアセンブリの境界を扱います。実務では「コンパイラ出力を読める」「呼び出し規約を守れる」ことが必須です。
このフェーズでは、Cとアセンブリの境界を扱います。実務では「コンパイラ出力を読める」「呼び出し規約を守れる」ことが必須です。
| 項目 | ルール |
|---|---|
| 整数引数 | rdi, rsi, rdx, rcx, r8, r9 の順 |
| 戻り値 | rax(必要に応じて rdx) |
| callee保存 | rbx, rbp, r12-r15 を関数内で破壊しない |
| stack整列 | 関数呼び出し時に16byte整列 |
Cコードをアセンブリへ変換して読む
gcc -O0 -g -S sample.c -o sample.s
less sample.s
オブジェクト逆アセンブルで対応を見る
gcc -O0 -g sample.c -o sample
objdump -d -M intel sample | less
最適化差分の観察
gcc -O0 -S sample.c -o o0.s
gcc -O2 -S sample.c -o o2.s
diff -u o0.s o2.s | less
int add_inline(int a, int b) {
int out;
__asm__ volatile (
"addl %[b], %[a]"
: [a] "=r" (out)
: "0" (a), [b] "r" (b)
: "cc"
);
return out;
}
volatile、出力制約、破壊リスト(clobber)を必ず明示します。
-O0 と -O2 の差分で最適化意図を説明する