2012-02-19 97 views
48

我想写一个小的低级程序。对于它的某些部分,我将需要使用汇编语言,但其余代码将用C/C++编写。因此,如果我将使用GCC将C/C++与汇编代码混合,是否需要使用AT & T语法或可以使用 我使用Intel语法?或者,你如何以其他方式混合使用C/C++和asm(intel语法)?我可以在GCC上使用x86汇编的Intel语法吗?

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

如果有证明是没有选择,在哪里可以找到全/有关AT & T语法的官方文档?

谢谢!

+0

如果你在asm中编写了一些完整的函数,它们可以在单独编译的文件中。如果您不介意对YASM或NASM构建依赖关系,那么可以轻松使用任何您喜欢的语法。 (但是,你的ASM必须处理Windows和Linux的不同ABI,也许使用汇编宏。)[GNU汇编程序手册在线](https://sourceware.org/binutils/docs/as/),以及通常与gcc/binutils一起安装。 ('info as')。 – 2015-12-01 02:18:41

+0

因为Clang的集成汇编器扼杀了Intel语法,所以要小心。另请参见[LLVM Issue 24232:内联汇编操作数不适用于.intel_syntax](http://llvm.org/bugs/show_bug.cgi?id=24232)。错误报告显示铿锵有一个简单否定的麻烦。 – jww 2016-07-24 13:30:56

回答

61

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

.intel_syntax noprefix 

它采用Intel语法,不需要寄存器名称前的前缀%。


如果使用内联汇编,你可以用-masm=intel

使用.intel_syntax noprefix在联汇编开始,然后再切换回与.att_syntax可以工作编译,但将打破,如果你使用任何m限制。存储器引用仍将在AT & T语法中生成。

+1

谢谢你,ninjalj !!!!!! – Hlib 2012-02-19 09:16:43

+12

Don'y忘记在组装部分结束时返回AT&T标准。 '.att_syntax noprefix'这样做。否则,汇编程序会尝试将编译器生成的汇编代码(AT&T格式)解释为英特尔格式。 – ugoren 2012-02-19 09:43:33

+7

@ugoren:'-masm = intel'使编译器生成Intel语法。你真的需要它用于内联汇编,否则'“m”'内存限制将不起作用。 – ninjalj 2012-02-19 09:49:27

4

您可以使用内联汇编,将-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; 
} 

当我建立这个代码时,我得到下面的错误消息。

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]' 

要避免这些错误,它需要内联组件(代码的上半部分),从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(); 
}