web-dev-qa-db-ja.com

GCCでx86アセンブリのIntel構文を使用できますか?

小さな低レベルのプログラムを書きたいです。その一部については、アセンブリ言語を使用する必要がありますが、残りのコードはC/C++で記述されます。

GCCを使用してC/C++とアセンブリコードを混在させる場合、AT&T構文を使用する必要がありますか、それともIntel構文を使用できますか?または、他の方法でC/C++とasm(Intel構文)をどのように混在させるのですか?

選択肢がなく、AT&T構文を使用する必要があることを理解していますが、確認したいのです。

そして、選択の余地がないことが判明した場合、AT&T構文に関する完全/公式のドキュメントを見つけることができますか?

ありがとう!

59
Hlib

別のアセンブリファイルを使用している場合、gasにはIntel構文をサポートするディレクティブがあります。

.intel_syntax noprefix

intel構文を使用し、レジスタ名の前に%プレフィックスを必要としません。


インラインアセンブリを使用している場合は、-masm=intelでコンパイルできます

インラインasmの先頭で.intel_syntax noprefixを使用し、.att_syntaxで元に戻すことはできますが、m制約を使用する場合は壊れますです。メモリ参照は引き続きAT&T構文で生成​​されます。

73
ninjalj

Ninjaljが書いたように、インラインアセンブリに-masm = intelを使用できますが、インラインアセンブリを使用して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]'

これらのエラーを回避するには、boost :: futureなどを必要とするC/C++コード(下半分)からインラインアセンブリ(コードの上半分)を分離する必要があります。 -masm = intelオプションは、他の.cppファイルではなく、Intel構文インラインアセンブリを含む.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();
}
7
Zettsu Tatsuya