Objetivos
-
Compreender o conceito de programa
- conceito de programa (entrada, processamento e saída)
- conceito de aplicação (na stack SO)
- processos “pai” e “filho”
-
Compreender que um ficheiro é composto por bits
- código ASCII
- código Assembly
- ficheiro executável (shell)
-
Compreender a estrutura de um progrma
- variável e função
- tipos int, char e float
-
Compreender o procedimento de compilação
- diretivas
-Se-g - programas
gcc,xxd,objdumpegcc
- diretivas
Para antes da aula
-
Assista o vídeo https://www.youtube.com/watch?v=RuKkePyo9zk e calcule a representação binária para 0.1 em IEEE 754.
-
Experimente o conversor: https://www.h-schmidt.net/FloatConverter/IEEE754.html
-
Consulte o livro recomendado para a UC de Sistemas de Computação, Essentials of Computing Systems, em especial as secções 3.5 e 3.6, pelo link: https://ebooks.uminho.pt/index.php/uminho/catalog/view/93/141/1786
O Código Fonte
#include <stdio.h>
int main(int argc, char **argv) {
float a = 2.0, b = 2.75, c = -(a + b);
float i = 0.1 + 0.1;
double j = 0.1 + 0.1;
printf("i: %f\n", i);
printf("j: %f\n", j);
int variavel;
variavel = argv[0][0];
return variavel; // ATENÇÃO: isto não se faz!
}
- Salvar o código acima num ficheiro
prog.c - Compilar o código com
gcc prog.c - Tipos primitivos
intnúmeros em binários e haxadecimalcharver tabela ASCII (https://www.ascii-code.com/)floatpadrão IEEE 754 (https://www.h-schmidt.net/FloatConverter/IEEE754.html)
O Ficheiro Binário (em ASCII)
Considere executar os comandos abaixo passando-os ao comando less.
A título de exemplo, para o primeiro comando é preferível escrever
xxd -b prog.c | less
-
Use o comando
xxd -b prog.cpara ver o ficheiro em binário -
Use o comando
xxd prog.cpara ver o ficheiro em hexadecimal -
Com base na tabela ASCII (https://www.ascii-code.com/) interprete o output
-
Use o comando
cat a.outpara ver o conteúdo do ficheiro (em ASCII)- use o
cat -v a.outpara os caracteres não imprimíveis - use o
cat --helpe oxxd --helppara outras opções
- use o
-
Use o comando
xxd a.outpara ver o ficheiro em hexadecimal- use o comando
xxd -i a.outpara ver o ficheiro no estilo C
- use o comando
Correndo o Código
- Executar o binário com
./a.out 2 - Ver o output com o comando
echo $?- o
argvé um array decharlogo,- argv[0] = “./a.out” e argv[1] = “2” == 50 (em ASCII decimal), assim
- argv[0][0] = ’.’ == 46, argv[0][1] = ’/’ = 47, …
- o
- Altere os parametros no programa e veja o que altera
O Ficheiro Assembly
- Gere o assembly do código com
gcc -S prog.ce seguidamente executecat prog.s - Gere um binário para debugging com
gcc -g prog.c- Use
objdump -S a.outpara ver o assembly - Relacione os endereços do
objdumpcom o doxxde observe como os mesmos bytes aparecem em ambos os ficheiros, num interpretado como ASCII e noutro como assembly.
- Use
Observar o Run time do Código
- Gere um binário para debugging com
gcc -g prog.c - Inicie o GDB com
gdb a.out - Mostre o programa que foi carregado com
list - Coloque um breakpoint na função
maincombreak main- execute
run 2e após parar no breakpoint, qual o valor doargce doargv? - mostre o valor do
argccomp argc(mostra o número de parâmetros) - qual o valor para
p argv[1][0]? - use
continuepara executar o resto do programa- deve exibir uma mensagem como
[Inferior 1 (process xxxxx) exited with code 062], aqui o código está em ASCII octal.
- deve exibir uma mensagem como
- execute
- Veja o efeito de diferentes modificadores de tipo
p /t 2p /t -2p /t (short) -2p /t (long) -2p (unsigned) 2p (unsigned) -2p /t (unsigned) -2p /t (unsigned) 2
- A representação dos inteiros chama-se complemento para dois
- consulte a secção correspondente no livro de SC e represente os números -9 e 11
- seguidamente imprima ambos os números com
p /tpara comparar os resultados com o que tinha calculado no ponto anterior
Sobre o tipo float
- Corra o
proge veja os valores parai,j - Inicie o gdb com o
prog - Avance até o
maincomstart - Depois avance até a linha 8 com
step- Mostre o valor de
icomp. Compare com o resultado doprintfe explique a razão disso. - Mostre o valor de
jcomp. Compare com o resultado doie explique a razão disso. - Altere o valor de
i,jpara 0.3 comset variable i = 0.3e exiba ambos valores comp. - Altere o valor de
i,jpara 0.1+0.2 comset variablee exiba ambos valores comp. - Repita o procedimento no programa e veja como o
printfse comporta.
- Mostre o valor de
- Altere o
ipara 0.1 comset variable- Veja a representação em binário com
x /t &i - Use o conversor (https://www.h-schmidt.net/FloatConverter/IEEE754.html)
- Veja a representação em binário com