3

GCCインラインアセンブリエラー:エラー:式の後のジャンク `(%esp)'

私はgccインラインアセンブリを研究しています。私の環境はWin732ビット、mingw-gcc4.6.1です。

'm'制約について問題があります。これが私のc関数コードです:

static int asm_test(int a, int b)
{

    int c = 0;
    __asm__ __volatile__(".intel_syntax\n"
            "mov eax, %1\n" //error
            "mov edx, %2\n" //error
            "add eax, edx\n"
            "mov %0, eax\n" //error
            ".att_syntax"
            :"=m"(c)\
            :"m"(a),"m"(b)\
            :"eax","edx"
            );
    return c;
}

at&tコードの場合、次のようになります。

static int asm_test(int a, int b)
{

    int c = 0;
    __asm__ __volatile__(
            "movl %1, $eax\n" //error
            "movl %2, $edx\n" //error
            "addl $edx, $eax\n"
            "movl $eax, %0\n" //error
            :"=m"(c)\
            :"m"(a),"m"(b)\
            :"eax","edx"
            );
    return c;
}

入出力オペランドを操作する3行のそれぞれについて、gccはコンパイル時にエラーを生成します。次のように読みます。

C:\ Users \ farta \ AppData \ Local \ Temp \ cc99HxYj.s:22:エラー:式の後のジャンク `(%esp)'

入出力制約に「r」を使用すると、コードは機能します。しかし、なぜそれが機能するのか、そしてエラーが何を意味するのか理解できません。誰か教えてもらえますか?私の知る限り、「m」はgccにレジスタを割り当てないように指示しているだけで、インラインasmコードが入力/出力オペランドにアクセスしようとした場合にメモリ内のレジスタに直接アクセスします。これは正しいです?

どうもありがとう。

4

1 に答える 1

4

ここでの問題は、GCCが、、およびのAT&T構文構造を生成する%0こと%1です%2。生成されたアセンブリを見ると、次のようになります。

.intel_syntax
mov eax, 8(%ebp)
mov edx, 12(%ebp)
add eax, edx
mov -4(%ebp), eax

これは有効なIntel構文ではありません。

通常、インラインアセンブリに明示的なロード/ストア操作を含める必要はありません。レジスタ制約を指定するだけで、コンパイラがロード/ストアを自動的に生成します。これには、変数(パラメータ、ローカル)がメモリにまったく存在しないが、レジスタにある場合でも、明示的にメモリのロード/ストアをそこに配置する場合とは異なり、コードは正しいという利点があります。

あなたの例では、次のコードを試して、アセンブリ(gcc -S)を見て、コンパイラが引数領域(x86のスタックなど)からの移動をすべて単独で実行する方法に注目してください。

int asm_test(int a, int b)
{
  __asm__ __volatile__ (
                        ".intel_syntax\n"
                        "add %0, %1 \n"
                        ".att_syntax \n"
                        :"+r"(a)
                        :"r"(b));
  return a;

}

于 2012-12-13T10:47:19.723 に答える