在GCC中切换Intel和ATT模式

时间:2015-01-25 10:49:33

标签: c gcc assembly nasm

所以我有这个内联汇编代码和我的C代码,我想对这个特定的asm()调用使用intel语法,但是我需要切换回ATT语法,否则它会给出很长的列表错误。

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

asm(".att_syntax prefix");

现在它出现以下错误

/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)'

我不明白如何修复错误,我在代码的任何部分都没有调用movl。

2 个答案:

答案 0 :(得分:2)

由于您尚未接受答案(< hint>< hint>),请允许我添加第三个想法:

1)不要使用3个asm语句,而是在1中执行:

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

2)将编译选项更改为包含-masm=intel并省略2个语法语句。

3)可以同时支持两者 intel和att。这样,您的代码可以处理为-masm传递的任何值:

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

我还应该提一下,你的asm可能无法按预期工作。由于您正在更新dst的内容(而不是覆盖它),您可能想要使用" + r"而不是" = r"。你确实意识到这段代码实际上并没有使用src,对吗?

哦,你原来的asm不是英特尔格式($ 1是赠品)。

答案 1 :(得分:0)

我会尝试进行以下测试:

在某些不包含内联汇编程序的C代码中插入行

asm(".att_syntax prefix");

在多个不同的位置。然后将C代码编译为目标文件并反汇编这些目标文件(编译成汇编程序不会为此测试工作)。

然后将原始代码的反汇编与包含" .att_syntax"的代码的反汇编进行比较。线。

如果行" .att_syntax前缀"确实是切换回AT& T模式的正确线路,反汇编必须相等并且编译必须正常工作而没有任何错误。

在下一步中,将代码转换为汇编程序而不是目标代码(" -S" GCC选项)。然后你可以查看汇编代码。

我的想法如下:

如果在内联汇编程序中使用数据交换(" = r"和" r"例如),GCC需要插入正在进行数据交换的代码:

 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");

GCC插入的代码当然是AT& T语法。

如果要在内联汇编中使用Intel语法,则必须使用" .att_syntax"和" .intel_syntax"同一内联汇编块中的指令,如下所示:

 // 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