インラインアセンブラと \n\t
小ネタ2。
GCCで複数行からなるインラインアセンブラを書くとき、
__asm__ ("movl %0,r9\n\t" "movl %1,r10\n\t" "call _foo" :: "g" (from), "g" (to) : "r9", "r10");
のように \n\t 区切りで書くひとと、\n\t のかわりにセミコロン区切りで書く*1ひとがいます。GCCのマニュアル上は、どちらでもOKよん、ということになってるんですが、世間では \n\t 派が多いです。...で、 ; の方が読みやすいだろうに、なぜ世間では\n\t派が多いのか、ちょっと前まで疑問でした。というわけで、\n\tの利点説明です。
gccコマンドが.cを食って一時ファイル(/tmp/ランダム文字列.s)を生成するとき、前者(\n\t)の書き方だと.sは
ラベル: #APP movl %0,r9 movl %1,r10 call _foo #NO_APP
のようになりますけど、後者(;)だと
ラベル: #APP movl %0,r9;movl %1,r10;call _foo #NO_APP
と一行になってしまい、(長〜い)インラインアセンブラ中にsyntax errorがあった場合などに、どこが間違っているのかgccのエラーメッセージ中の行番号からはさっぱりわからなくなってしまいます。全部同一の行番号ですから。前者なら、gcc -save-temps -c hoge.c として hoge.s を取り出し、行番号をもとに文法ミスを修正することができます。
以上、
- __asm__ の中身はわりと単純に.sへブチ込まれるだけだということを(もう一度)思いだそう。
- GCCの、 .c -> .s -> .o 完全分業体制は不便、うーん。
みたいな話でした。