INF1018 - Software Básico - 2011.1

Aulas de Laboratório

Código de Máquina

  1. Traduza a função abaixo para assembler:

    int foo (int x) {
      return x+1;
    }
    

  2. Use gcc -m32 -c foo.s para traduzir seu programa para linguagem de máquina (o gcc vai gerar um arquivo foo.o). Veja qual o código de máquina que seu programa gera, usando ou objdump -d foo.o ou a opção -Wa,-al do gcc.

  3. Escreva agora um programa em C como descrito a seguir. Esse programa deve criar um array de bytes (unsigned char) preenchido com o código de máquina visto no item anterior. A seguir, ele deve converter o endereço do array para um endereço de função. Para isso, declare o tipo ponteiro para função recebendo int e retornando int, conforme abaixo:

    typedef int (*funcp) (int x);
    
    A seguir, atribua o endereço do array a uma variável do tipo acima:
    funcp f = (funcp)a;
    
    Agora, você pode chamar f como se fosse uma função C normal, por exemplo:
    i = (*f)(10);
    
    Faça isso no seu programa. Pode ser necessário compilar seu programa com gcc -m32 -Wall -Wa,--execstack seuprograma.c para permitir a execução do seu código de máquina. Execute o programa resultante.

    Dica: a função dump pode ser útil se você precisar "inspecionar" o código gerado...

  4. Experimente agora gerar o código para a seguinte função:
    int foo2(int a, int b) [
      int c = a + 1;
      c = c + b;
      return c;
    }
    
    Aloque a variável local c na pilha.

    Teste o código gerado com alguns valores diferentes para a e b.

  5. Experimente agora passar os valores de a e b como argumentos na linha de comando.