¿Puedo usar la sintaxis Intel del ensamblado x86 con GCC?


Quiero escribir un pequeño programa de bajo nivel. Para algunas partes necesitaré usar lenguaje ensamblador, pero el resto del código será escrito en C / C++.

Entonces, si voy a usar GCC para mezclar C / C++ con código ensamblador, ¿necesito usar la sintaxis de AT & T o can ¿Uso sintaxis Intel? ¿O cómo se mezcla C / C++ y asm (sintaxis intel) de alguna otra manera?

Me doy cuenta de que tal vez no tengo otra opción y debo usar la sintaxis de AT&T, pero quiero estar seguro..

Y si resulta que no hay elección, ¿dónde puedo encontrar documentación completa / oficial sobre la sintaxis de AT & T?

Gracias!

Author: Mysticial, 2012-02-19

2 answers

Si está utilizando archivos de ensamblaje separados, gas tiene una directiva para admitir la sintaxis de Intel:

.intel_syntax noprefix

Que usa sintaxis Intel y no necesita el prefijo % antes de los nombres de registro.


Si está utilizando ensamblado en línea, puede compilar con -masm=intel

Usar .intel_syntax noprefix al inicio del asm en línea, y cambiar de nuevo con .att_syntaxpuede funcionar, pero se romperá si usa cualquier restricción m. La referencia de memoria se seguirá generando en la sintaxis de AT&T.

 66
Author: ninjalj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-01 02:15:02

Puede usar ensamblado en línea con-masm=intel como ninjalj escribió, pero puede causar errores cuando incluye encabezados de C/C++ usando ensamblado en línea. Este es el código para reproducir los errores en 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;
}

Cuando construí este código, recibí mensajes de error a continuación.

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

Para evitar estos errores, necesita separar el ensamblado en línea (la mitad superior del código) del código C/C++ que requiere boost::future y similares (la mitad inferior). La opción-masm=intel se utiliza para compilar .cpp archivos que contienen Intel syntax inline assembly, no a otros .archivos 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();
}
 5
Author: Zettsu Tatsuya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-05 11:11:27