2012-02-19 117 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(); 
}