4月
13
式の置き換えを行う .equ
ディレクティブの扱いが異なることがあるようです。
int main(void) { int ret; asm volatile( ".intel_syntax noprefix\n" ".equ hoge, eax\n" "mov hoge, 42\n" : "=a"(ret)); return ret; }
これを GCC でコンパイルすると、mov hoge, 42
は mov eax, 42
に置き換わり、eax レジスタに 42 を mov する意味になります。
一方、Clang でコンパイルすると、eax はレジスタではなく変数(メモリの位置)だと解釈され、mov dword ptr [eaxという変数のアドレス], 42
に置き換わります(64bit 環境なら qword ptr
になる)。そんな変数は無いのでリンクエラーになります。
ただ、これは Clang の方が適切な動作のようにも思えます。なぜならレジスタとしての eax はアセンブリ言語における式 (expression) ではないからです。
代わりに以下のようなコードだとどちらでも OK です。 .irp
ではマクロ展開と同じく文字列として置き換えを行うからです。
int main(void) { int ret; asm volatile( ".intel_syntax noprefix\n" ".irp hoge, eax\n" "mov \hoge, 42\n" ".endr\n" : "=a"(ret)); return ret; }
ただ、 .irp
には対応する .endr
が必要であるため、複数個定義すると .endr
がたくさん出てきて見た目が残念なことになります。
no comment untill now