我可以在GCC中使用x86汇编的Intel语法吗?

Hli*_*lib 59 c x86 assembly gcc inline-assembly

我想写一个小的低级程序.对于它的某些部分,我将需要使用汇编语言,但其余代码将使用C/C++编写.

那么,如果我使用GCC将C/C++与汇编代码混合在一起,我是否需要使用AT&T语法,还是可以使用Intel语法?或者你如何以其他方式混合使用C/C++和asm(intel语法)?

我意识到也许我没有选择,必须使用AT&T语法,但我想确定..

如果结果没有选择,我可以在哪里找到有关AT&T语法的完整/官方文档?

谢谢!

nin*_*alj 72

如果您使用单独的汇编文件,gas有一个支持Intel语法的指令:

.intel_syntax noprefix
Run Code Online (Sandbox Code Playgroud)

它使用Intel语法,并且在寄存器名称之前不需要%前缀.


如果您使用的是内联汇编,则可以使用 -masm=intel

.intel_syntax noprefix在内联asm的开头使用,并切换回.att_syntax可以工作,但如果使用任何约束将会中断m.内存引用仍将以AT&T语法生成.

  • 不要忘记在装配部分结束时返回AT&T标准.`.att_syntax noprefix`就是这么做的.否则,汇编程序将尝试将编译器生成的汇编代码(采用AT&T格式)解释为Intel格式. (12认同)
  • @ugoren:`-masm = intel`使编译器生成Intel语法.你真的需要它用于内联汇编,否则`"m"`内存约束将不起作用. (7认同)
  • @ugoren:如果你使用`.intel_syntax`而不使用`-masm = intel`,`"m"`将以AT&T语法提供内存引用.如果使用`-masm = intel`,则不需要(也不应该)返回AT&T,因为编译器输出Intel语法. (5认同)
  • 我认为混合它们听起来是个坏主意。要么接受 AT&T 语法(这很奇怪,但你可以学会接受),要么一直使用 Intel 语法。 (3认同)
  • 撤消`.intel_syntax noprefix`需要`.att_syntax noprefix`.我很确定你也可以使用带有AT&T语法的`"m".这只是一个方便的问题,AFAIK. (2认同)

小智 7

你可以使用内联汇编和-masm = intel作为ninjalj编写,但是当你使用内联汇编包含C/C++头文件时它可能会导致错误.这是重现Cygwin错误的代码.

sample.cpp:
#include <cstdint>
#include <iostream>
#include <boost/thread/future.hpp>

int main(int argc, char* argv[]) {
    using Value = uint32_t;
    Value value = 0;
    asm volatile (
        "mov  %0, 1\n\t"   // Intel syntax
//      "movl $1, %0\n\t"  // AT&T  syntax
        :"=r"(value)::);

    auto expr = [](void) -> Value { return 20; };
    boost::unique_future<Value> func { boost::async(boost::launch::async, expr) };
    std::cout << (value + func.get());
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我构建此代码时,我收到以下错误消息.

g++ -E -std=c++11 -Wall -o sample.s sample.cpp
g++ -std=c++11 -Wall -masm=intel -o sample sample.cpp -lboost_system -lboost_thread
/tmp/ccuw1Qz5.s: Assembler messages:
/tmp/ccuw1Qz5.s:1022: Error: operand size mismatch for `xadd'
/tmp/ccuw1Qz5.s:1049: Error: no such instruction: `incl DWORD PTR [rax]'
/tmp/ccuw1Qz5.s:1075: Error: no such instruction: `movl DWORD PTR [rcx],%eax'
/tmp/ccuw1Qz5.s:1079: Error: no such instruction: `movl %eax,edx'
/tmp/ccuw1Qz5.s:1080: Error: no such instruction: `incl edx'
/tmp/ccuw1Qz5.s:1082: Error: no such instruction: `cmpxchgl edx,DWORD PTR [rcx]'
Run Code Online (Sandbox Code Playgroud)

为了避免这些错误,它需要将内联汇编(代码的上半部分)与需要boost :: future等(下半部分)的C/C++代码分开.-masm = intel选项用于编译包含Intel语法内联汇编的.cpp文件,而不是其他.cpp文件.

sample.hpp:
#include <cstdint>
using Value = uint32_t;
extern Value GetValue(void);

sample1.cpp: compile with -masm=intel
#include <iostream>
#include "sample.hpp"
int main(int argc, char* argv[]) {
    Value value = 0;
    asm volatile (
        "mov  %0, 1\n\t"   // Intel syntax
        :"=r"(value)::);
    std::cout << (value + GetValue());
    return 0;
}

sample2.cpp: compile without -masm=intel
#include <boost/thread/future.hpp>
#include "sample.hpp"
Value GetValue(void) {
    auto expr = [](void) -> Value { return 20; };
    boost::unique_future<Value> func { boost::async(boost::launch::async, expr) };
    return func.get();
}
Run Code Online (Sandbox Code Playgroud)