11 - Revisão¶
Na aula de hoje iremos revisar nossas atividades com Assembly e representação de inteiros.
Quando tiver dúvidas, chame o professor ou os ninjas!
Importante
Esta aula tem duas partes:
- Exercícios de revisão (
ex1.c
,ex2.c
,ex3.c
eex4.c
)- Siga o roteiro para desenvolvê-los
- Simulado de prova
- Veja mais detalhes no final do roteiro!
Ex1.c¶
Abra o código-fonte ex1.c
e confira a função main
. Compile e execute o exercício 1. Em seguida, responda:
Exercise
O valor apresentado na saída confere com o presente no código? Por que isto acontece?
Answer
O valor -1 em complemento de 2 é representado como uma sequência de 1's. Ao ser atribuído em uma unsigned short, teremos dezesseis 1's, mas que serão interpretados como unsigned. Somando 2^0 + 2^1 + \dots + 2^{15} = 65535
Exercise
Qual o maior valor que pode ser armazenado em uma variável unsigned short?
Answer
A variável será de 2 bytes sem sinal, assim o maior valor é 2^{16}-1 = 65535
Exercise
O que acontece quando tentamos armazenar um valor maior que o suportado pelo tipo de dados? Ex: atribuir 80000
para uma unsigned short.
Answer
Apenas os 16 bits menos significativos serão considerados.
Ex2.c¶
Neste exercício iremos fazer engenharia reversa de Assembly para C. Os códigos-fonte estão disponíveis no repositório, mas evite abri-los antes de ter feito pelo menos uma primeira versão da engenharia reversa.
Compile o ex2.c
com
$ gcc -Wall -std=c99 -Og ex2.c -c -o ex2.o
Abra o arquivo ex2.o
com o gdb sem abrir o código-fonte e responda:
Exercise
Liste as variáveis globais e funções existentes.
Answer
Funções func1
e func2
. Sem variáveis globais.
Analise a função func1
com o gdb e responda:
Exercise
Com base nos registradores utilizados, escreva a assinatura da função func1
.
Answer
void func1(unsigned short *vec)
%rdi
, são feitas várias atribuições espaçadas em dois bytes, indicando ser um ponteiro para short
.
Exercise
Em movw $0x0,(%rdi)
, qual a operação realizada e o que significa o trecho (%rdi)
?
Answer
A operação é vec[0] = 0
ou *vec = 0
. Como a operação é um MOV
, então (%rdi)
representa uma dereferenciação de ponteiro.
Tip
Veja a seção Acesso a elementos constantes da aula 09 - Arrays
Exercise
Em movw $0x14,0x4(%rdi)
, qual a operação realizada e o que significa o trecho 0x4(%rdi)
?
Answer
A operação é vec[2] = 20
. Em 0x4(%rdi)
, indicamos que queremos acessar o endereço %rdi + 4 bytes.
Tip
Acese na aula 05-Condicionais a explicação sobre as variântes da instrução mov
Exercise
Faça uma versão legível em C da função func1
.
Answer
void func1(unsigned short *vec) {
vec[0] = 0;
vec[1] = 10;
vec[2] = 20;
}
Analise a função func2
com o gdb e responda:
Exercise
Com base nos registradores utilizados, escreva a assinatura da função func2
.
Answer
void func2(int *vec, int n)
Exercise
Qual a operação realizada em lea (%rax,%rax,4),%edx
na função func2
?
Answer
É uma operação aritmética onde o valor armazenado em %rax
é multiplicado por 5 e armazenado em %edx
.
Exercise
Qual a operação realizada em add %edx,%edx
na função func2
?
Answer
É uma operação aritmética onde o valor armazenado em %edx
é somado consigmo mesmo e armazenado em %edx
. Isto é equivalente a fazer var = var * 2
.
Exercise
Você conseguiria agregar as operações lea (%rax,%rax,4),%edx
e add %edx,%edx
em uma única operação aritmética mais simples?
Answer
Supondo que %eax
representa a variável i
, então a junção das duas operações é equivalente a fazer i * 10
, cujo resultado é armazenado em %edx
.
Exercise
Faça uma versão em C do código acima usando somente if-goto
. Escreva, então, ao lado desta versão um código legível em C.
Answer
Versão if-goto
:
void func2(int *vec, int n) {
int i = 0;
int aux;
goto test;
loop:
aux = i * 5;
aux = aux + aux;
vec[i] = aux;
i = i + 1;
test:
if (i < n) {
goto loop:
}
return;
}
Versão C
:
void func2(int *vec, int n) {
for (int i = 0; i < n; i++) {
vec[i] = i * 10;
}
}
Ex3.c¶
Neste exercício iremos fazer engenharia reversa de Assembly para C. Os códigos-fonte estão disponíveis no repositório, mas evite abri-los antes de ter feito pelo menos uma primeira versão da engenharia reversa.
Compile o ex3.c
com:
$ gcc -Wall -std=c99 -Og ex3.c -o ex3
Abra o arquivo ex3
com o gdb sem abrir o código-fonte e responda:
Exercise
Liste as funções e variáveis globais disponíveis.
Answer
Variável global v_global
. Funções func1
, func2
, func3
, func4
e main
.
Exercise
Faça a tradução das funções func1
e func2
. Existe alguma semelhança?
Answer
Ambas fazem operações com registradores. Porém func2
faz a leitura de algum valor de memória e armazenando no retorno da função, uma variável global. Já func1
apenas faz uma operação aritmética com o parâmetro recebido.
int func1(int n) {
int x = 10;
return x + n;
}
int func2(int n) {
return v_global + n;
}
Tip
Fique atento a chamadas de variáveis globais. Utilize o comando x
para imprimir o conteúdo de um endereço. Veja mais em https://sourceware.org/gdb/current/onlinedocs/gdb#Memory
Exemplo:
x/d 0x100
x/s 0x100
Exercise
Defina a assinatura da função func3
e faça sua tradução para C.
Answer
int func3(int n, int mult) {
return v_global + n * mult;
}
Exercise
Defina a assinatura da função func4
. Faça uma versão em C do código acima usando somente if-goto
. Escreva, então, ao lado desta versão um código legível em C.
Answer
Versão if-goto
:
void func4() {
res = func1(5);
if (res <= 20) {
goto faz_algo;
}
printf("O novo valor eh maior que 20");
retorna:
return;
faz_algo:
printf("O novo valor nao eh maior que 20");
goto retorna;
}
Versão C
:
void func4() {
int aux = func1(5);
if (aux > 20) {
printf("O novo valor eh maior que 20");
} else {
printf("O novo valor nao eh maior que 20");
}
}
Ex4.c¶
Neste exercício iremos fazer engenharia reversa de Assembly para C. Os códigos-fonte estão disponíveis no repositório, mas evite abri-los antes de ter feito pelo menos uma primeira versão da engenharia reversa.
Compile o ex4.c
com:
$ gcc -Wall -std=c99 -fno-stack-protector -Og ex4.c -o ex4
Abra o arquivo ex4
com o gdb sem abrir o código-fonte e responda:
Exercise
Defina a assinatura da função ex4
. Faça uma versão em C do código acima usando somente if-goto
. Escreva, então, ao lado desta versão um código legível em C.
Answer
Versão if-goto
:
int ex4() {
unsigned short n; // variavel na pilha
int ret;
int i;
int aux;
scanf("%hu", &n);
i=1;
goto test;
loop:
ret = ret + i*4;
i = i+1;
test:
aux = n;
if (aux > i) {
goto loop;
}
return ret;
}
Versão C
:
#include <stdio.h>
int ex4() {
unsigned short n;
scanf("%hu", &n);
int res = 0;
int i = 1;
while (i < n) {
res += (i*4);
i++;
}
return res;
}
int main() {
return 0;
}
Tip
Observe sempre as chamadas de variáveis globais e strings (relativos a %rip
) e acessos à stack (relativos a %rsp
).
Simulado de prova¶
Além dos exercícios de revisão feitos na aula, você encontrará no repositório da disciplina um arquivo simulado_ai.zip
.
Na AI, vocês receberão um arquivo semelhante a este. No dia da prova, você terá que baixar o zip, descompactar, resolver os exercícios, compactar novamente e anexar no Blackboard.
Tip
Leia o README.md
ou README.html
para saber o que é esperado em cada questão!
Tip
Leia o README.md
ou README.html
para saber como você será avaliado!