INF1018 - Software Básico - 2011.2

Aulas de Laboratório

Compilação e link-edição

  1. Considere o programa formado pelos arquivos abaixo:

    Note que os arquivos temp1.h e temp2.h contém declarações dos simbolos globais exportados, respectivamente, por temp1.c e temp2.c A inclusão desses arquivos garante a consistência dessas declarações entre os módulos, tanto para os arquivos que definem os símbolos quanto para os que os importam.

    Compile, ligue e execute esse programa, seguindo os passos abaixo:
    > gcc -m32 -c -Wall temp1.c
    > gcc -m32 -c -Wall temp2.c
    > gcc -m32 -o prog  temp1.o temp2.o
    
    (Você poderia fazer tudo de uma só vez chamando gcc -m32 -Wall temp1.c temp2.c, mas aí o gcc não gera os arquivos .o.)
  2. Use o programa nm para inspecionar os símbolos usados por cada módulo (chame nm temp1.o e nm temp2.o). Você consegue inferir o significado das letras que aparecem na saída deste programa (U, T, etc.)? (Dica: google "man nm".)

  3. Troque no 1o arquivo (temp1.c) a linha int a = 1024; por char a = 1; e recompile esse módulo. O que acontece?

    Você percebe como a inclusão dos arquivos de header inclusive pelos módulos que definem os símbolos garante a consistência das declarações?

  4. Restabeleça no arquivo temp1.c declaração int a = 1024;

  5. Restaure a inclusão de "temp1.h" no 2o arquivo (temp2.c), e remova a declaração "local" static char a = 0;.

    Agora remova no primeiro arquivo (temp1.c) a linha #include "temp2.h" (isto é, a declaração dos símbolos exportados por temp2).

    Troque em temp1.c a linha foo(); por b(); Recompile e execute o programa. (Atenção: Gere o executável com gcc -m32 -o prog -Wa,--execstack temp1.c temp2.c) . O que acontece?

    Repita com o valor inicial de b sendo 0xC3. O que acontece agora?

    Certifique-se que você entendeu o que aconteceu nos dois casos!