Esercitazione 2 - 10 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 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 (
gcc -m32 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, xx=
20, yy=
10;
res = max
(&xx,&yy
);
printf("max(&xx,&yy)=%-3d [xx=%-3d, yy=%-3d]\n", res, xx, yy
);
xx =
-10; yy =
1;
res = max
(&xx,&yy
);
printf("max(&xx,&yy)=%-3d [xx=%-3d, yy=%-3d]\n", res, xx, yy
);
return 0;
}
Nota bene: compilare a 32 bit con
gcc -m32.
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.
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;
}
Si tenga presente che non è possibile usare due operandi memoria: ad esempio
cmpb (%eax), (%ecx) è illegale. 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.
Esercizio 5
Tradurre in C la seguente funzione IA32 generata con
gcc -m32 -O1 in un modulo
es5.c:
.globl mistero
mistero:
movl 8(%esp), %eax
cmpl 12(%esp), %eax
jnb .L3
movl 4(%esp), %edx
movzwl (%edx,%eax,2), %eax
ret
.L3:
movl $-1, %eax
ret
Scrivere un programma di prova
es5-main.c per verificare la correttezza della funzione.
Esercizio 6
Tradurre in C la seguente funzione IA32 generata con
gcc -m32 -O1 in un modulo
es6.c:
.globl mistero
mistero:
movl 4(%esp), %edx
movl 8(%esp), %eax
jmp .L2
.L4:
movzwl -4(%edx,%eax,2), %ecx
subl $1, %eax
cmpw (%edx,%eax,2), %cx
ja .L5
.L2:
cmpl $1, %eax
ja .L4
movl $1, %eax
ret
.L5:
movl $0, %eax
ret
Scrivere un programma di prova
es6-main.c per verificare la correttezza della funzione.
Esercizio 7
Domande su operandi e modi di indirizzamento della memoria IA32
Esercizio 8
Domande su istruzioni aritmetico-logiche IA32
Soluzioni Esercizi 1-6
Sono di sponibili le
soluzioni degli esercizi 1-6