GCC inline assembly error: Error: junk `(%esp)' after expression

末鹿安然 提交于 2019-12-01 08:19:17

问题


GCC inline assembly error: Error: junk `(%esp)' after expression

I'm studying gcc inline assembly. My environment is Win 7 32bit, mingw-gcc 4.6.1.

I have got a problem about the 'm' constraint. Here is my c function code:

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;
}

For at&t code, it is like this:

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;
}

For each of the three lines which operate input/output operands, gcc generate an error when compiling, read like this:

C:\Users\farta\AppData\Local\Temp\cc99HxYj.s:22: Error: junk `(%esp)' after expression

If i use 'r' for input/output constraint, the code will work. But I cannot understand why it works and what the error stands for. Can anyone tell me? As far as I know 'm' is just telling gcc not to allocate registers but directly access them in memory if inline asm code try to access input/output operands. Is this correct?

Thanks a lot.


回答1:


The problem here is the GCC generates AT&T syntax construct for %0, %1 and %2. If you look at the generated assembly, it looks like:

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

which is not a valid Intel syntax.

Generally, you don't need to include in the inline assembly explicit load/store operation - just specify register constraint and the compiler will generate loads/stores by itself. This has the advantage that even if your variables (parameters, locals) do not reside in memory at all, but are in registers your code will still be correct - unlike in the case if you explicitly put memory load/stores there.

For your example, try the following code, look at the assembly (gcc -S) and notice how the compiler will perform moves from argument area (e.g. stack on x86) all by itself.

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;

}



来源:https://stackoverflow.com/questions/13856792/gcc-inline-assembly-error-error-junk-esp-after-expression

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!