c++ - ejemplos - Etiquetas en ensamblaje en línea de GCC
meta tags ejemplos (2)
Bueno, esta pregunta no se está volviendo más joven, pero hay otras dos soluciones interesantes.
1) Este ejemplo usa% =. % = en una plantilla de ensamblador se reemplaza por un número que es "único para cada ins en toda la compilación. Esto es útil para hacer etiquetas locales a las que se hace referencia más de una vez en una entrada determinada". Tenga en cuenta que para usar% =, usted (al parecer) debe tener al menos una entrada (aunque probablemente no tenga que usarla realmente).
int a = 3;
asm (
"test %0/n/t"
"jnz to_here%=/n/t"
"jz to_there%=/n/t"
"to_here%=:/n/t"
"to_there%=:"
::"r" (a));
Esto produce:
test %eax
jnz to_here14
jz to_there14
to_here14:
to_there14:
Alternativamente, puede usar el asm goto (agregado en v4.5, creo). Esto realmente te permite saltar a las etiquetas c en lugar de a las etiquetas asm:
asm goto ("jmp %l0/n"
: /* no output */
: /* no input */
: /* no clobber */
: gofurther);
printf("Didn''t jump/n");
// c label:
gofurther:
printf("Jumped/n");
En mi constante experimentación con el ensamblado en línea de GCC, me encontré con un nuevo problema relacionado con las etiquetas y el código en línea.
Considere el siguiente salto simple:
__asm__
(
"jmp out;"
"out:;"
:
:
);
Esto no hace más que saltar a la etiqueta de out
. Como es, este código compila bien. Pero si lo coloca dentro de una función y luego compila con indicadores de optimización, el compilador se queja: "Error: el símbolo ''out'' ya está definido".
Lo que parece estar sucediendo es que el compilador repite este código de ensamblaje cada vez que indica la función. Esto provoca que la etiqueta se duplique, lo que genera varias etiquetas de out
.
Entonces, ¿cómo puedo solucionar esto? ¿Realmente no es posible usar etiquetas en el ensamblaje en línea? Este tutorial sobre ensamblaje en línea de GCC menciona que:
Por lo tanto, puede hacer que su ensamblaje entre las macros CPP y las funciones en línea C, para que cualquiera pueda usarlo como cualquier función C / macro. Las funciones en línea se parecen mucho a las macros, pero a veces son más limpias de usar. Tenga en cuenta que en todos esos casos, el código se duplicará, por lo que solo las etiquetas locales (de 1: estilo) se deben definir en ese código asm.
Traté de encontrar más información sobre estas "etiquetas locales", pero parece que no puedo encontrar nada relacionado con el ensamblaje en línea. Parece que el tutorial dice que una etiqueta local es un número seguido de dos puntos (como 1:
, así que traté de usar una etiqueta como esa. Curiosamente, el código compilado, pero en tiempo de ejecución simplemente desencadenó una falla de segmentación. Hmm ...
Entonces, ¿alguna sugerencia, pistas, respuestas ...?
Una declaración de una etiqueta local es de hecho un número seguido de dos puntos. Pero una referencia a una etiqueta local necesita un sufijo de f
o b
, dependiendo de si desea mirar hacia adelante o hacia atrás, es decir, 1f
refiere a la siguiente etiqueta 1:
hacia adelante.
Entonces, declarar la etiqueta como 1:
es correcto; pero para referenciarlo, necesitas decir jmp 1f
(porque estás saltando hacia adelante en este caso).