简体   繁体   中英

Switching between Intel and ATT mode in GCC

So I have this inline assembly code along with my C code, and I want to use intel syntax for this particular call to asm(), however I need to switch back to ATT syntax or else it will give a long list of errors.

asm(".intel_syntax prefix");
     asm volatile (
        "add %0, $1 \n\t"
         : "=r" (dst)
         : "r" (src)); 

asm(".att_syntax prefix");

Now it gives the following error

/tmp/ccDNa2Wk.s: Assembler messages:
/tmp/ccDNa2Wk.s:180: Error: no such instruction: `movl -16(%ebp),%eax'
/tmp/ccDNa2Wk.s:187: Error: no such instruction: `movl %eax,-12(%ebp)'

I dont understand how to fix the error, i have no call to movl in any part of my code.

Since you haven't yet accepted an answer (<hint><hint>), let me add a third thought:

1) Instead of having 3 asm statements, do it in 1:

asm(".intel_syntax prefix\n\t"
    "add %0, 1 \n\t"
    ".att_syntax prefix"
     : "=r" (dst)
     : "r" (src));

2) Change your compile options to include -masm=intel and omit the 2 syntax statements.

3) It is possible to support both intel and att at the same time. This way your code works whatever value is passed for -masm:

asm("{addl $1, %0 | add %0, 1}"
     : "=r" (dst)
     : "r" (src));

I should also mention that your asm may not work as expected. Since you are updating the contents of dst (instead of overwriting it), you probably want to use "+r" instead of "=r". And you do realize that this code doesn't actually use src, right?

Oh, and your original asm is NOT intel format (the $1 is the give-away).

I would try to do the following tests:

In some C code not containing inline assembler insert the line

asm(".att_syntax prefix");

in multiple different locations. Then compile the C code to object files and disassemble these object files (compiling to assembler won't work for this test).

Then compare the disassembly of the original code with the disassembly of the code containing the ".att_syntax" lines.

If the line ".att_syntax prefix" indeed is the correct line for switching back to AT&T mode the disassemblies must be equal AND compiling must work without any errors.

In the next step take your code and compile to assembler instead of object code ("-S" option of GCC). Then you can look at the assembler code.

My idea is the following one:

If you use data exchange in inline assembler ("=r" and "r" for example) GCC needs to insert code that is doing the data exchange:

 asm(".intel_syntax prefix");
 // GCC inserts code moving "src" to "%0" here
 asm volatile (
    "add %0, $1 \n\t"
     : "=r" (dst)
     : "r" (src)); 
 // GCC inserts code moving "%0" to "dst" here
 asm(".att_syntax prefix");

This code inserted by GCC is of course in AT&T syntax.

If you want to use Intel syntax in inline assembly you have to use the ".att_syntax" and ".intel_syntax" instructions in the same inline assembly block, just like this:

 // GCC inserts code moving "src" to "%0" here
 asm volatile (
    ".intel_syntax prefix \n\t"
    "add %0, $1 \n\t"
    ".att_syntax prefix \n\t"
     : "=r" (dst)
     : "r" (src)); 
 // GCC inserts code moving "%0" to "dst" here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM