Additions:
Sono disponibili le [[http://www.dis.uniroma1.it/~sc/wikka.php?wakka=SolEserc03AA1516 soluzioni]] dell'esercitazione.
Deletions:
Le soluzioni dell'esercitazione sono disponibili [[http://www.dis.uniroma1.it/~sc/wikka.php?wakka=SolEserc03AA1516 qui]].
Additions:
===Soluzioni===
Le soluzioni dell'esercitazione sono disponibili [[http://www.dis.uniroma1.it/~sc/wikka.php?wakka=SolEserc03AA1516 qui]].
Additions:
unsigned i = 0;
Deletions:
unsigned i;
Additions:
**Nota importante:** fare attenzione che i registri ##A##, ##C## e ##D## (i registri caller-save) potrebbero essere **sovrascritti** da una chiamata a funzione, quindi **il loro valore potrebbe andare perso** dopo la chiamata. Si suggerisce pertanto di usare registri callee-save: ##B##, ##SI##, ##DI##, ##BP## (es. ##ebx##, ##esi##, ##edi##, ##ebp##).
**Nota importante:** fare attenzione che i registri ##A##, ##C## e ##D## (i registri caller-save) potrebbero essere **sovrascritti** da una chiamata a funzione, quindi **il loro valore potrebbe andare perso** dopo la chiamata. Si suggerisce pertanto di usare registri callee-save: ##B##, ##SI##, ##DI##, ##BP## (es. ##ebx##, ##esi##, ##edi##, ##ebp##).
Deletions:
**Nota importante:** fare attenzione che i registri ##A##, ##C## e ##D## (i registri caller-save) potrebbero essere **sovrascritti** da una chiamata a funzione, quindi **il loro valore potrebbe andare perso** dopo la chiamata.
**Nota importante:** fare attenzione che i registri ##A##, ##C## e ##D## (i registri caller-save) potrebbero essere **sovrascritti** da una chiamata a funzione, quindi **il loro valore potrebbe andare perso** dopo la chiamata.
Additions:
==Esercizio 5 (chiamata a funzione con parametri in un ciclo)==
Tradurre in IA32 la seguente funzione C in un modulo ##es5.s##:
%%(c;es5.c)
int doppio(int x);
int raddoppia(int* v, unsigned n) {
unsigned i;
while (i
v[i] = doppio(v[i]);
i++;
}
Testare il funzionamento della funzione scritta con il seguente programma di prova ##es5-main.c## e il modulo ##es5-doppio.s## che fornisce il codice della funzione ##doppio##:
%%(c;es4-doppio.s)
# int doppio(int x) {
# return x+x;
.globl doppio
doppio:
addl %eax, %eax
movl $-1, %ecx # sovrascrive C (a scopi di test)
movl $-1, %edx # sovrascrive D (a scopi di test)
%%(c;es5-main.c)
int raddoppia(int* v, unsigned n);
int i, v[] = {10, 20, 30, 40, 50};
raddoppia(v, 5);
for (i=0; i<5; i++) printf("v[%d]=%d\n", i, v[i]);
Additions:
**Nota importante:** fare attenzione che i registri ##A##, ##C## e ##D## (i registri caller-save) potrebbero essere **sovrascritti** da una chiamata a funzione, quindi **il loro valore potrebbe andare perso** dopo la chiamata.
Deletions:
**Nota importante:** fare attenzione che i registri ##A##, ##C## e ##D## vengono **sovrascritti** dalla chiamata alla funzione ##prod##, quindi **il loro valore non si conserva** dopo la chiamata.
Additions:
int prod(int x, int y, int z);
int f(int x, int y, int z, int w) {
return prod(x,y,z)+w;
**Nota importante:** fare attenzione che i registri ##A##, ##C## e ##D## vengono **sovrascritti** dalla chiamata alla funzione ##prod##, quindi **il loro valore non si conserva** dopo la chiamata.
Deletions:
int prod(int x, int y);
int f(int x, int y, int z) {
return prod(x,y)+z;
Additions:
Testare il funzionamento della funzione scritta con il seguente programma di prova ##es4-main.c## e il modulo ##es4-prod.s## che fornisce il codice della funzione ##prod##:
%%(c;es4-prod.s)
# int prod(int x, int y, int z) {
# return x*y*z;
# }
.globl prod
prod:
movl 4(%esp), %eax
movl 8(%esp), %ecx
movl 12(%esp), %edx
imull %ecx, %eax
imull %edx, %eax
ret
int f(int x, int y, int z, int w); // calcola x*y*z+w
res = f(2,3,4,6);
printf("f(2,3,4,6)=%d\n", res);
Deletions:
Testare il funzionamento della funzione scritta con il seguente programma di prova ##es4-main.c## e modulo ##es4-prod.c## che fornisce il codice della funzione ##prod##:
%%(c;es4-prod.c)
int prod(int x, int y) {
return x*y;
int f(int x, int y, int z); // calcola x*y+z
res = f(2,3,4);
printf("f(2,3,4)=%d\n", res);
Additions:
res = f(2,3,4);
printf("f(2,3,4)=%d\n", res);
Additions:
%%(c;es1-main.c)
%%(c;es2-main.c)
%%(c;es3-main.c)
==Esercizio 4 (chiamata a funzione con parametri)==
Tradurre in IA32 la seguente funzione C in un modulo ##es4.s##:
%%(c;es4.c)
int prod(int x, int y);
int f(int x, int y, int z) {
return prod(x,y)+z;
Testare il funzionamento della funzione scritta con il seguente programma di prova ##es4-main.c## e modulo ##es4-prod.c## che fornisce il codice della funzione ##prod##:
%%(c;es4-prod.c)
int prod(int x, int y) {
return x*y;
%%(c;es4-main.c)
int f(int x, int y, int z); // calcola x*y+z
Deletions:
%%(c;es1-test.c)
%%(c;es2-test.c)
%%(c;es3-test.c)
Additions:
==Esercizio 3 (chiamata a funzione senza parametri)==
Tradurre in IA32 la seguente funzione C in un modulo ##es3.s##:
%%(c;es3.c)
int uno();
int somma_uno_a(int x) {
return x+uno();
%%(c;es3-test.c)
int somma_uno_a(int x);
int uno() { return 1; }
res = somma_uno_a(20);
printf("somma_uno_a(20)=%d\n", res);
Additions:
int myabs(int x) {
int myabs(int x);
printf("myabs(10)=%d\n", res);
printf("myabs(-10)=%d\n", res);
printf("myabs(0)=%d\n", res);
Deletions:
int myabs(char x) {
short myabs(char x);
short res;
printf("myabs(10)=%hd\n", res);
printf("myabs(-10)=%hd\n", res);
printf("myabs(0)=%hd\n", res);
Additions:
==Esercizio 2 (istruzione ##CMOVcc##)==
Tradurre in IA32 la seguente funzione C in un modulo ##es2.s##, usando l'istruzione ##CMOVcc##, **senza usare istruzioni di salto** (##Jcc## o ##JMP##):
%%(c;es2.c)
int myabs(char x) {
return x<0 ? -x : x;
%%(c;es2-test.c)
short myabs(char x);
short res;
res = myabs(10);
printf("myabs(10)=%hd\n", res);
res = myabs(-10);
printf("myabs(-10)=%hd\n", res);
res = myabs(0);
printf("myabs(0)=%hd\n", res);
**Nota bene:** compilare a 32 bit con ##gcc -m32##.
Additions:
res = testcc(-15,-20);
printf("testcc(-15,-20)=%d\n", res);
Additions:
==Esercizio 1 (istruzione ##SETcc##)==
Tradurre in IA32 la seguente funzione C in un modulo ##es1.s##, usando l'istruzione ##SETcc##:
int testcc(short x, short y) {
return 0<=x && x
int testcc(short x, short y);
res = testcc(10,20);
printf("testcc(10,20)=%d\n", res);
res = testcc(-10,20);
printf("testcc(-10,20)=%d\n", res);
res = testcc(15,10);
printf("testcc(15,10)=%d\n", res);
Deletions:
==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;
int uguali(short x, short y);
res = uguali(10,20);
printf("uguali(10,20)=%d\n", res);
res = uguali(-30,-30);
printf("uguali(-30,-30)=%d\n", res);