在 GCC 中切换 Intel 和 ATT 模式

Switching between Intel and ATT mode in GCC

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

asm(".intel_syntax prefix");
     asm volatile (
        "add %0,  \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。

我会尝试做以下测试:

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

asm(".att_syntax prefix");

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

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

如果行“.att_syntax prefix”确实是切换回 AT&T 模式的正确行,则反汇编必须相等并且编译必须无任何错误。

在下一步中,将您的代码编译为汇编程序而不是目标代码(GCC 的“-S”选项)。然后你可以看看汇编代码

我的想法是:

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

 asm(".intel_syntax prefix");
 // GCC inserts code moving "src" to "%0" here
 asm volatile (
    "add %0,  \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,  \n\t"
    ".att_syntax prefix \n\t"
     : "=r" (dst)
     : "r" (src)); 
 // GCC inserts code moving "%0" to "dst" here

由于您还没有接受答案(<提示><提示>),让我添加第三个想法:

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) 可以同时支持both intel和att。这样,无论为 -masm:

传递什么值,您的代码都可以工作
asm("{addl , %0 | add %0, 1}"
     : "=r" (dst)
     : "r" (src));

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

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