Laboratório 1 - Semana de 22 Fev
-
Download dos ficheiros necessários:
- Faça o download do ficheiro fact.tgz
.
- Descomprima o ficheiro com o comando:
$ tar xvfz fact.tgz
Foi criado um directório "fact" com o conteúdo do ficheiro. - Entre dentro desse directório com o comando:
$ cd fact
- Liste os ficheiros com o comando:
$ ls -l
- Faça o download do ficheiro fact.tgz
-
Compilação:
- Visualize o ficheiro
main.c
com um editor de texto à sua escolha (ex: gedit, emacs, vi, kate, sublime, etc.)- declaração da função main: argumentos e tipo de retorno.
- valores de retorno.
- função do programa
- includes e globais
- ver
fact.h
,iter.c
erecurs.c
- Compile os módulos fonte do programa iterativo e faça a ligação do código objecto resultante para produzir o
executável.
$ gcc -ansi -pedantic -Wall -o iter main.c iter.c
- Execute o programa e verifique que este imprime o factorial de 5.
- Visualize o ficheiro
-
Depuração de um programa usando o gdb / ddd (facultativo)
- Consulte os apontamentos sobre o gdb disponíveis.
- Defina um ponto de quebra (breakpoint) no seu programa no início da função que calcula o valor do factorial (double
click na barra lateral na linha desejada).
- Recorrendo à linha de comandos execute o programa passo a passo a partir do breakpoint com comando next. Verifique o valor das variáveis a cada passo da execução do programa.
-
Passos intermédios do processo de compilação (facultativo):
- Pré-processamento: fase que antecede a compilação e que executa as directivas iniciadas por #. Por exemplo, no
ficheiro
main.c
serão processadas as directivas#include
e#define
.
$ gcc -E main.c
O resultado do pré-processamento é enviado para o terminal. (O pré processador pode ser invocado separadamente com o comandocpp
) - Compilação: fase que gera código final em assembly. O assembly ainda tem um formato textual, pode ser lido e
modificado por um vulgar editor de texto, mas o código gerado já depende do processador, arquitectura e sistema
operativo.
$ gcc -S iter.c
Verifique o código assembly gerado no ficheiroiter.s
. Compare as variantes do ficheiroiter.s
quando utiliza o optimizador (adicionar a opção-O
) e a informação para o debugger (adicionar a opção-g
). - Montagem ou assemblagem: fase que produz os códigos binários, ficheiros objecto (".o", nada tem a ver com
linguagens orientada para objectos), que serão processados pelo CPU. Esta fase é independente da linguagem de alto nível
utilizada: C, Pascal, Fortran, etc.
$ gcc -c main.c
Verifique o tipo de ficheiro gerado, com o comando:
$ file main.o
e as dimensões das secções, com o comando:
$ size main.o
e a tabela de símbolos, com o comando:
$ nm main.o
(O assemblador pode ser invocado separadamente com o comandoas
) - Ligação ou Linkagem: fase que produz o ficheiro executável final através da interligação dos vários ficheiros
objectos ou de bibliotecas (conjuntos de ficheiros objecto).
$ gcc -o factorial main.o iter.s
Verifique o tipo de ficheiro gerado e as dimensões das secções. Use o comandoldd
para verificar as dependências das bibliotecas dinâmicas. Tente gerar um ficheiro executável com as variantes iterativa e recursiva, simultaneamente,
$ gcc main.c iter.c recurs.c
e verifique que existem duas realizações de factorial com o mesmo nome. Por outro lado, se tentar criar um ficheiro executável apenas com o ficheiromain.c
,
$ gcc main.c
falta um ficheiro ou biblioteca que forneça uma realização de factorial. - O processo completo (executável estático vs dinâmico): o comando
gcc
permite, como já pode observar, controlar todo o processo de compilação para a linguagem C. Contudo, pode verificar a execução das diversas fases através da opção-v
.
$ gcc -v -static main.c iter.c
Neste exemplo, geramos um executável estático, isto é, não depende na execução da existência das bibliotecas dinâmicas. Como contrapartida, o executável final fica muito maior, pois inclui no próprio ficheiro uma cópia de todas as funções utilizadas, como por exemplo oprintf
. Verifique o tipo, dimensões do ficheiro (ls -l
), dimensões das secções e dependências do ficheiroa.out
gerado, face ao executável dinâmico gerado na alínea anterior. Retire a informação simbólica, com o comandostrip
, e verifique que o executável ficou mais pequeno e que já não é possível saber a posição dos símbolos (comandonm
). - Faça o download do ficheiro fact-makefile.zip . Inspeccione o exemplo de ficheiro "Makefile" com um editor de texto e crie os dois executáveis através do comando make. Consulte os apontamentos sobre Makefiles, e procure na web outras referências sobre esta matéria.
- Pré-processamento: fase que antecede a compilação e que executa as directivas iniciadas por #. Por exemplo, no
ficheiro