その2の続き

Intel 記法と Input Operand (の一部の制約)は併用できないわけですが、手持ちのソースを AT&T 記法に変換するのもチョー大変なので別の方法を。

x86 の場合、こういうものを書けます。

int foo(int x)
{
        int ret;
        asm volatile(
                ".intel_syntax\n"
                "mov  eax, ecx\n"
                : "=a"(ret)
                : "c"(x) );
        return ret;
}

"c"(x) によって ecx に x の値を入れてからインラインアセンブリブロックが挿入されます。この方法だと、インラインアセンブリブロック内のプログラムに対してオペランドを埋め込む処理は起こらないため、Clang でも対応できます。c 以外にも a b d S D が使えるので、合計6つのオペランドをレジスタで渡すことができます。残念ながら ebp は使えません。

この方法を取る場合の欠点は以下のようになります。

  • x86 の場合、6つまでしか渡せない。7つ以上渡すには一旦配列に書いておいて、アドレスをレジスタ渡しするといった工夫が必要。
  • x64 の場合、レジスタはたくさんあるので14個まで渡せるが、r8 以降を使う場合は Input Operands は使えず、explicit register variable を使う必要がある(書き方が違ってくる)
  • アセンブリブロックの先頭では不要だけど途中で必要になってくるメモリオペランドを扱えない。レジスタで受け取って push して置いておく、といった工夫が必要

思ったより大変じゃなかった。

Trackback

no comment untill now

Add your comment now