Esercitazione 3 - 17 novembre 2015 (90 min)
Aprire Linux LXLE nella VM Oracle Virtualbox BIAR.
Creare una
directory di lavoro sc1516 sulla scrivania e posizionarsi nella directory creata come segue:
$ mkdir /home/biar/Desktop/sc1516
$ cd /home/biar/Desktop/sc1516
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<y;
}
Testare il funzionamento della funzione scritta con il seguente programma di prova:
#include <stdio.h>
int testcc
(short x,
short y
);
int main
() {
int res;
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
);
res = testcc
(-15,
-20);
printf("testcc(-15,-20)=%d\n", res
);
return 0;
}
Nota bene: compilare a 32 bit con
gcc -m32 (
gcc -m32 es1-main.c es1.s -o es1).
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):
int myabs(int x) {
return x<0 ? -x : x;
}
Testare il funzionamento della funzione scritta con il seguente programma di prova:
#include <stdio.h>
int myabs
(int x
);
int main
() {
int res;
res = myabs
(10);
printf("myabs(10)=%d\n", res
);
res = myabs
(-10);
printf("myabs(-10)=%d\n", res
);
res = myabs
(0);
printf("myabs(0)=%d\n", res
);
return 0;
}
Nota bene: compilare a 32 bit con
gcc -m32.
Esercizio 3 (chiamata a funzione senza parametri)
Tradurre in IA32 la seguente funzione C in un modulo
es3.s:
int uno();
int somma_uno_a(int x) {
return x+uno();
}
Testare il funzionamento della funzione scritta con il seguente programma di prova:
#include <stdio.h>
int somma_uno_a
(int x
);
int uno
() { return 1;
}
int main
() {
int res;
res = somma_uno_a
(20);
printf("somma_uno_a(20)=%d\n", res
);
return 0;
}
Nota bene: compilare a 32 bit con
gcc -m32.
Esercizio 4 (chiamata a funzione con parametri)
Tradurre in IA32 la seguente funzione C in un modulo
es4.s:
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 (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).
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:
# 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
#include <stdio.h>
int f
(int x,
int y,
int z,
int w
);
// calcola x*y*z+w
int main
() {
int res;
res = f
(2,
3,
4,
6);
printf("f(2,3,4,6)=%d\n", res
);
return 0;
}
Nota bene: compilare a 32 bit con
gcc -m32.
Esercizio 5 (chiamata a funzione con parametri in un ciclo)
Tradurre in IA32 la seguente funzione C in un modulo
es5.s:
int doppio(int x);
int raddoppia(int* v, unsigned n) {
unsigned i = 0;
while (i<n) {
v[i] = doppio(v[i]);
i++;
}
}
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).
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:
# int doppio(int x) {
# return x+x;
# }
.globl doppio
doppio:
movl 4(%esp), %eax
addl %eax, %eax
movl $-1, %ecx # sovrascrive C (a scopi di test)
movl $-1, %edx # sovrascrive D (a scopi di test)
ret
#include <stdio.h>
int raddoppia
(int* v,
unsigned n
);
int main
() {
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
]);
return 0;
}
Nota bene: compilare a 32 bit con
gcc -m32.
Soluzioni
Sono disponibili le
soluzioni dell'esercitazione.