Gcc Inline Assembly

Como coloco una instruccin de "no operation" dentro de mi cdigo?

int main (void)
{
    __asm__ ("nop");
}

Procedemos a compilar utilizando el modificador -S, el cual le dice a gcc que compile pero no linkee, dejandonos como resultado un fuente en assembly (sintaxis AT&T). Es decir, ejecutamos gcc -S ejemplo1.c con lo que obtendramos un ejemplo1.s conteniendo algo similar a esto:

        .file   "ejemplo1.c"
        .section .text
.globl _main
_main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        andl    $-16, %esp
        movl    $0, %eax
        subl    %eax, %esp
/APP
        nop
/NO_APP
        leave
        ret
        .ident  "GCC: (GNU) 3.2.3"

De donde salio todo ese cdigo si lo nico que escrib fue un "nop"? Es aqu donde eran necesarios los conocimientos de assembly :-) . Por el momento basta con que sepas que las funciones en C reciben sus argumentos a travs del stack, y es en ese mismo lugar donde "viven" las variables locales. Si bien nuestro "main" no recibe argumentos ni define variables locales, el Gcc arma la estructura como si las usara. Es entre las lineas /APP y /NO_APP que aparece nuestro cdigo.

NOTA: Estas lneas fueron compiladas utilizando el DJGPP. El cdigo de salida puede variar ligeramente dependiendo del compilador.

.Otro ejemplo sencillo

Veamos otro ejemplo simple para los que an se sientan confundidos:

int main(void)
{
    __asm__ ("movl $0xdead, %eax");
}

Luego de ejecutar gcc -S ejemplo2.c obtenemos:

        .file   "ejemplo2.c"
        .section .text
.globl _main
_main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        andl    $-16, %esp
        movl    $0, %eax
        subl    %eax, %esp
/APP
        movl $0xdead, %eax
/NO_APP
        leave
        ret
        .ident  "GCC: (GNU) 3.2.3"

NOTA: es necesario colocar antes de los datos inmediatos el operando "$" para que el gcc lo intrprete correctamente, mientras que a los registros debe anteponerse un "%". Como vern el inline assembly bsico no representa gran utilidad, excepto en algunos casos como los que se describen a continuacin.

.Ejemplos ms tiles

Ahora

__asm__ ("sti");

El cual habilita las interrupciones enmascarables del microprocesador. Es bastante comun encontrarse con alguna de las siguientes definiciones:

#define enable()    __asm__ __volatile__ ("sti")
        o
#define sti()       __asm__ __volatile__ ("sti")

las cuales son visualmente mas agradables que su contraparte utilizando inline assembly.

Veamos algn otro ejemplo til del inline assembly comn:

__asm__ __volatile__ ("pushf ; cli");
        .
        .
    cdigo crtico
        .
        .
__asm__ __volatile__ ("popf");

En este caso no hacemos mas que bloquear las interrupciones para un fragmento de cdigo crtico, el cul no puede ser interrumpido. El uso del PUSHF y POPF en lugar de un simple CLI y STI me aseguran que las interrupciones al finalizar mi cdigo quedarn en el estado que estaban antes de que yo las deshabilite.

COMPARTE ESTE ARTÍCULO

ENVIAR A UN AMIGO
COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN GOOGLE +
SIGUIENTE ARTÍCULO

¡SÉ EL PRIMERO EN COMENTAR!
Conéctate o Regístrate para dejar tu comentario.