2012-02-19 15 views
48

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++.¿Puedo usar la sintaxis Intel del ensamblaje x86 con GCC?

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

que darse cuenta de que tal vez no tengo una elección y deben utilizar al & sintaxis T, pero quiero estar seguro ..

Y si no resulta ser otra opción, donde puedo encontrar completa/documentación oficial sobre la sintaxis de AT & T?

Gracias!

+0

Si escribe algunas funciones completas en asm, pueden estar en un archivo compilado por separado. Si no te importa una dependencia de compilación en YASM o NASM, entonces es fácil usar la sintaxis que prefieras. (Pero entonces su asm tiene que lidiar con los diferentes ABIs para Windows y Linux, tal vez con macros del ensamblador.) El [manual de ensamblador de GNU está en línea] (https://sourceware.org/binutils/docs/as/), y también generalmente instalado con gcc/binutils. ('información como'). –

+0

Tenga cuidado con la sintaxis de Intel porque el ensamblador integrado de Clang se atasca en él. Ver también [24232 Edición LLVM: Inline operandos de montaje no funcionan con .intel_syntax] (http://llvm.org/bugs/show_bug.cgi?id=24232). El informe de error muestra que Clang tiene problemas con un simple rechazo. – jww

Respuesta

61

Si está utilizando archivos de ensamblaje por separado, el gas tiene una directiva para apoyar Intel sintaxis:

.intel_syntax noprefix 

que utiliza la sintaxis de Intel y no necesita el prefijo% antes de nombres de registro.


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

Usando .intel_syntax noprefix al comienzo de asm en línea, y cambiar de nuevo con .att_syntax puede trabajar, pero romperá si se utiliza cualquier m restricciones La referencia de memoria se generará aún en AT & T sintaxis.

+1

Gracias, ninjalj !!!!!! – Hlib

+12

No olvide devolver el estándar de AT & T al final de su sección de ensamblaje. '.att_syntax noprefix' hace esto. De lo contrario, el ensamblador intentará interpretar el código ensamblador generado por el compilador, que está en formato AT & T, como formato Intel. – ugoren

+7

@ugoren: '-masm = intel' hace que el compilador genera sintaxis de Intel.Realmente lo necesita para el ensamblaje en línea, de lo contrario '' m "' las restricciones de memoria no funcionarán. – ninjalj

4

Puede utilizar ensamblado en línea con -masm = Intel como escribió ninjalj, pero puede causar errores cuando se incluyen C/C++ utilizando encabezados ensamblado 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í los siguientes mensajes de error.

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, se necesita para separar ensamblado en línea (la mitad superior del código) a partir de C/C++ código que requiere impulso :: futuro 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(); 
} 
Cuestiones relacionadas