code assembler asm gcc assembly inline-assembly i386

gcc - asm - use assembler in c



Comportamiento inesperado de ASM en lĂ­nea de GCC(sobreescritura de la variable cruzada) (1)

El ensamblaje en línea de GCC es una programación avanzada, con muchas trampas. Asegúrese de que realmente lo necesita, y no puede reemplazarlo con el módulo de ensamblaje independiente, o el código C usando intrínsecos. o soporte vectorial.

Si insistes en el ensamblaje en línea, debes estar preparado para al menos mirar el código ensamblador generado y tratar de descubrir cualquier error a partir de allí. Obviamente, el compilador no omite nada de lo que escriba en el bloque asm, simplemente sustituye los argumentos. Si miras el código generado, es posible que veas algo como esto:

add %dx, %ax mov %ax, %dx

Aparentemente el compilador eligió dx para el argumento 0 y 1 . Está permitido hacer eso, porque por defecto asume que los argumentos de entrada se consumen antes de que se escriban las salidas. Para señalar que este no es el caso, debe usar un modificador de clobber temprano para su operando de salida, para que se vea como "=&r" .

PD: incluso cuando el ensamblaje en línea parece funcionar, puede tener problemas ocultos que te morderán otro día, cuando el compilador hace otras elecciones. Realmente deberías evitarlo.

En mi computadora, el ejecutable compilado omite la ejecución de "mov% 2, %% axe" en la parte superior del ciclo

cuando "agregar% 1, %% ax" sin comentar.

¿Alguien para verificar o comentar?

#include <stdio.h> int main() { short unsigned result, low ,high; low = 0; high = 1; __asm__ ( "movl $10, %%ecx /n/t" "loop: mov %2, %%ax /n/t" // "add %1, %%ax /n/t" // uncomment and result = 10 "mov %%ax, %0 /n/t" "subl $1, %%ecx /n/t" "jnz loop" : "=r" (result) : "r" (low) , "r" (high) : "%ecx" ,"%eax" ); printf("%d/n", result); return 0; }

Sigue el montaje generado

movl $1, %esi xorl %edx, %edx /APP movl $10 ,%ecx loop: mov %si, %ax mov %dx, %bx add %bx, %ax mov %ax, %dx subl $1, %ecx jnz loop /NO_APP

Gracias a Jester la solución:

: "=&r" (result) // early clober modifier