2008-09-14 20 views
46

Recuerdo que en el día con el viejo DOS Borland compilador que podría hacer algo como esto:¿Hay alguna forma de insertar el código de ensamblaje en C?

asm { 
mov ax,ex 
etc etc... 
} 

¿Hay una manera independiente semi-plataforma para hacer esto ahora? Necesito hacer una llamada al BIOS, por lo que si hubiera una forma de hacerlo sin el código asm, eso me sería igualmente útil.

+0

Consulte también los enlaces en la [wiki de la etiqueta de montaje en línea] (https://stackoverflow.com/tags/inline-assembly/info) para saber cómo hacerlo bien. Es difícil, y la mejor sugerencia es https://gcc.gnu.org/wiki/DontUseInlineAsm. Para el rendimiento, siempre que sea posible, modifique su código fuente para ayudar al compilador a crear un mejor código, en lugar de usar el asm en línea. (por ejemplo, mirando la salida del asm del compilador para ver qué no optimiza o qué hace mal). –

Respuesta

54

Usando GCC

__asm__("movl %edx, %eax\n\t" 
     "addl $2, %eax\n\t"); 

Usando VC++

__asm { 
    mov eax, edx 
    add eax, 2 
} 
+0

C++ Builder, de CodeGear, también admite la palabra clave __asm. – stukelly

+0

¡El compilador VS no es compatible con el ensamblaje en línea! ¡Me había quemado el dedo tratando de hacer eso hace unos años! –

+2

@JayD: el compilador de VS admite el ensamblaje en línea según el objetivo. Por ejemplo, es compatible con 32 bits x86; 64-bit x86-64 no lo es. –

4

Un buen comienzo sería estar leyendo este artículo que habla de ensamblado en línea en C/C++:

http://www.codeproject.com/KB/cpp/edujini_inline_asm.aspx

Ejemplo del artículo:

#include <stdio.h> 


int main() { 
    /* Add 10 and 20 and store result into register %eax */ 
    __asm__ ("movl $10, %eax;" 
       "movl $20, %ebx;" 
       "addl %ebx, %eax;" 
    ); 

    /* Subtract 20 from 10 and store result into register %eax */ 
    __asm__ ("movl $10, %eax;" 
        "movl $20, %ebx;" 
        "subl %ebx, %eax;" 
    ); 

    /* Multiply 10 and 20 and store result into register %eax */ 
    __asm__ ("movl $10, %eax;" 
        "movl $20, %ebx;" 
        "imull %ebx, %eax;" 
    ); 

    return 0 ; 
} 
9

En GCC, hay más que eso. En la instrucción, tienes que decirle al compilador qué cambió, para que su optimizador no se estropee. No soy un experto, pero a veces se ve algo como esto:

asm ("lock; xaddl %0,%2" : "=r" (result) : "0" (1), "m" (*atom) : "memory"); 

Es una buena idea para escribir un código de ejemplo en C, a continuación, pedir GCC para producir una lista de montaje, a continuación, modificar ese código.

2

Los compiladores de Microsoft no x86 no son compatibles con el ensamblaje en línea. Debe definir la función completa en un archivo fuente de ensamblaje separado y pasarla a un ensamblador.

Es muy poco probable que pueda llamar al BIOS en un sistema operativo en modo protegido y debería usar las instalaciones disponibles en ese sistema. Incluso si está en el modo kernel, probablemente no sea seguro: el BIOS puede no estar sincronizado correctamente con respecto al estado del sistema operativo si lo hace.

+0

Mike, ¿qué quiere decir con "compiladores de Microsoft no x86 no son compatibles con ensamblado en línea", por supuesto puede tener, por ejemplo, Montaje en línea ARM (no x86), solo búsquelo. –

+1

"El ensamblaje en línea no es compatible con los procesadores ARM y x64". - https://docs.microsoft.com/en-gb/cpp/assembler/inline/inline-assembler. * Ensamblador * en línea significa el uso de bloques '__asm', y estoy hablando específicamente de los compiladores de Microsoft. Aún puede crear un archivo .asm por separado, ensamblarlo con el ensamblador de Microsoft (ML/ML64/armasm) y vincular el .obj resultante con un programa C/C++ utilizando CL. Las otras respuestas indican que puede realizar el ensamblaje en línea con otros compiladores. –

Cuestiones relacionadas