Esercitazione 2 - 21 ottobre 2016 (120 min)
Preliminari
Prima di iniziare l'esercitazione, creare un file con nome "
.gdbinit" nella directory
/home/biar (nella VM BIAR) con il seguente contenuto:
define go
start
layout src
layout regs
focus cmd
end
che consente di dare il comando
go per fare il debugging di un programma C/IA32. Per debuggare un programma
mioprog, dare
gdb ./mioprog e poi il comando
go. Riepilogo dei comandi:
- go: esegue uno script che lancia il debugging del programma e si ferma sulla prima istruzione del main
- step (oppure s): esegue una singola istruzione, entrando nelle funzioni chiamate
- next (oppure n): esegue una singola istruzione, considerando le chiamate a funzione come singole istruzioni
- finish: completa l'esecuzione della funzione corrente
- cont: completa l'esecuzione del programma
- x/d addr: mostra il contenuto dell'int all'indirizzo addr. Esempio: x/d $esp + 4 mostra l'intero all'indirizzo 4(%esp).
- i r reg1 reg2 ...: mostra il contenuto dei registri reg1, reg2, ecc, sia in base 16 che in base 10. Esempio: i r $eax $ecx.
Osservazione sulle istruzioni IA32
Si tenga presente che:
- non è possibile usare due operandi memoria: ad esempio cmpb (%eax), (%ecx) è illegale.
- non è possibile usare un operando immediato per la destinazione: ad esempio cmpl %eax, $0 è illegale.
Esercizio 1 (istruzione if, parametri senza indirezione)
Tradurre in IA32 la seguente funzione C in un modulo
es1.s:
int uguali(short x, short y) {
int res = 0;
if (x == y) res = 1;
return res;
}
Testare il funzionamento della funzione scritta con il seguente programma di prova:
#include <stdio.h>
int uguali
(short x,
short y
);
int main
() {
int res;
res = uguali
(10,
20);
printf("uguali(10,20)=%d\n", res
);
res = uguali
(-30,
-30);
printf("uguali(-30,-30)=%d\n", res
);
return 0;
}
Nota bene: compilare a 32 bit con
gcc -m32 -g (
gcc -m32 -g es1-main.c es1.s -o es1).
Esercizio 2 (istruzione if, parametri con indirezione)
Tradurre in IA32 la seguente funzione C in un modulo
es2.s:
int max(int* x, int* y) {
if (*x > *y) return *x;
return *y;
}
Testare il funzionamento della funzione scritta con il seguente programma di prova:
#include <stdio.h>
int max
(int* x,
int* y
);
int main
() {
int res, a=
20, b=
10;
res = max
(&a,&b
);
printf("max(&a,&b)=%-3d [a=%-3d, b=%-3d]\n", res, a, b
);
a =
-10; b =
1;
res = max
(&a,&b
);
printf("max(&a,&b)=%-3d [a=%-3d, b=%-3d]\n", res, a, b
);
return 0;
}
Nota bene: compilare a 32 bit con
gcc -m32 -g.
Esercizio 3 (istruzione while, somma dei numeri da 1 a n)
Tradurre in IA32 la seguente funzione C in un modulo
es3.s:
unsigned sum1N(unsigned n) {
unsigned sum = 0;
while (n>=1) sum += n--;
return sum;
}
Testare il funzionamento della funzione scritta con il seguente programma di prova:
#include <stdio.h>
unsigned sum1N
(unsigned n
);
int main
() {
unsigned res;
res = sum1N
(4);
printf("sum1N(4)=%u\n", res
);
res = sum1N
(0);
printf("sum1N(0)=%u\n", res
);
return 0;
}
Nota bene: compilare a 32 bit con
gcc -m32 -g.
Esercizio 4 (istruzione while, uguaglianza di stringhe C)
Tradurre in IA32 la seguente funzione C in un modulo
es4.s:
int streq(const char* s1, const char* s2) {
while (*s1 == *s2)
if (*s1 == 0) return 1;
else s1++, s2++;
return 0;
}
Testare il funzionamento della funzione scritta con il seguente programma di prova:
#include <stdio.h>
int streq
(const char* s1,
const char* s2
);
int main
() {
int res;
res = streq
("ciao",
"ciao");
printf("streq(\"ciao\", \"ciao\")=%d\n", res
);
res = streq
("ciaos",
"ciao");
printf("streq(\"ciaos\", \"ciao\")=%d\n", res
);
res = streq
("ciac",
"ciao");
printf("streq(\"ciac\", \"ciao\")=%d\n", res
);
res = streq
("cia",
"ciao");
printf("streq(\"cia\", \"ciao\")=%d\n", res
);
res = streq
("",
"");
printf("streq(\"\", \"\")=%d\n", res
);
return 0;
}
Nota bene: compilare a 32 bit con
gcc -m32 -g.