assembler - ¿Puedo usar la sintaxis Intel del ensamblaje x86 con GCC?
use assembler in c (2)
Puede usar el ensamblaje en línea con -masm = intel como escribió ninjalj, pero puede causar errores cuando incluye encabezados C / C ++ usando el ensamblaje en línea. Este es un 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, debe separar el ensamblaje 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 archivos .cpp que contienen ensamblado en línea de sintaxis Intel, 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();
}
Quiero escribir un pequeño programa de bajo nivel. Para algunas partes, necesitaré usar lenguaje ensamblador, pero el resto del código se escribirá en C / C ++.
Entonces, si voy a usar GCC para mezclar C / C ++ con código ensamblador, ¿necesito usar la sintaxis AT & T o puedo usar la sintaxis Intel? ¿O cómo se mezclan 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 otra opción, ¿dónde puedo encontrar documentación completa / oficial sobre la sintaxis de AT & T?
¡Gracias!
Si está utilizando archivos de ensamblaje por separado, el gas tiene una directiva para admitir la sintaxis de Intel:
.intel_syntax noprefix
que usa la sintaxis de Intel y no necesita el prefijo% antes de los nombres de registro.
Si está utilizando ensamblado en línea, puede compilar con -masm=intel
El uso de .intel_syntax noprefix
al inicio del asm en línea, y la conmutación de regreso con .att_syntax
puede funcionar, pero se romperá si usa cualquier m
restricción. La referencia de memoria se generará en la sintaxis de AT & T.