#include <stdio.h>

int main(int argc, char **argv)
{
    // Criando variáveis para interagir com assembly:
    int foo, bar, var;
    
    // O código abaixo mudará o valor de foo usando assembly.
    // NOTA: A sintaxe assembly depende do compilador.
    //       No caso do GCC, usa-se o estilo AT&T por padrão,
    //       mas é possível usar o estilo Intel também.
    
    // Exemplo 1:
    //    Em C, seria:
    //        foo = 1;
    //        bar = 2;
    //        var = 3;
    asm volatile ("movl $1, %0;"  // código assembly
                  "movl $2, %1;"
                  "movl $3, %2;"
                  : "=g" (foo), "=g" (bar), "=g" (var) // variáveis de saída
                  );
                  
    printf("EXEMPLO 1:\nfoo = %d\nbar = %d\nvar = %d\n\n", foo, bar, var);
                  
    // Exemplo 2:
    //    Em C, seria:
    //        bar = foo * 2;
    asm volatile ("movl $2, %%eax;"      // eax = 2
                  "imul %%ebx, %%eax;"   // eax * ebx
                  "movl %%eax, %0;"      // faz bar igual ao resultado.
                  : "=r" (bar)    // variáveis de saída
                  : "b" (foo)     // variáveis de entrada (ebx = foo)
                  ); 
                      
    printf("EXEMPLO 2:\nbar = %d \n\n", bar);
    
    // Exemplo 3:
    //    Em C, seria:
    //        var = bar;
    asm volatile ("movl %0, %%eax;"
                  "movl %%eax, %1;"
                  : "=r" (var)
                  : "b" (bar)
                  : "%eax"
                  ); 

    printf("EXEMPLO 3:\nvar = %d \n\n", var);

    return 0;
}
