Можно ли использовать синтаксис Intel сборки x86 с GCC? - PullRequest
59 голосов
/ 19 февраля 2012

Я хочу написать небольшую низкоуровневую программу.Для некоторых его частей мне нужно будет использовать язык ассемблера, но остальная часть кода будет написана на C / C ++.

Так что, если я буду использовать GCC для смешивания C / C ++ с кодом ассемблера, сделайтеМне нужно использовать синтаксис AT & T или я могу использовать синтаксис Intel?Или как вы смешиваете C / C ++ и asm (синтаксис Intel) каким-то другим способом?

Я понимаю, что, возможно, у меня нет выбора и я должен использовать синтаксис AT & T, но я хочу быть уверен ...

А если не будет выбора, где я могу найти полную / официальную документацию о синтаксисе AT & T?

Спасибо!

Ответы [ 2 ]

73 голосов
/ 19 февраля 2012

Если вы используете отдельные файлы сборки, у gas есть директива для поддержки синтаксиса Intel:

.intel_syntax noprefix

, который использует синтаксис Intel и не нуждается в префиксе% перед именами регистров.


Если вы используете встроенную сборку, вы можете скомпилировать с -masm=intel

Использование .intel_syntax noprefix в начале встроенного asm и переключение обратно с помощью .att_syntax может работать, но нарушит , если вы используете какие-либо ограничения m. Ссылка на память будет по-прежнему генерироваться в синтаксисе AT & T.

7 голосов
/ 05 января 2017

Вы можете использовать встроенную сборку с -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 ++, который требует boost :: future и т.п. (нижняя половина).Опция -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();
}
...