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