Esercizi traduzione da C ad Assembly IA32
Si vedano le discussioni e le soluzioni sul
forum.
Esercizio 1: assegnamento e calcolo di espressioni
Tradurre in IA32 la seguente funzione C, mantenendo la variabile x nel registro A:
short expr() {
short x=(20-2)*(7+3)+2*(10-7);
return x;
}
Se si ritiene che servano registri di appoggio per il calcolo dell'espressione, usare preferibilmente i registri C e/o D.
- Suggerimento: come visto a lezione, strutturare la traduzione C -> IA32 in due passi: prima riformulare il programma C in una forma equivalente in cui ogni istruzione ha al più due operandi, e poi effettuare la traduzione in IA32. Ad esempio, riscrivere int x=2+5 (che ha tre operandi x, 2 e 5) come: int x=2; x=x+5, che può essere poi immediatamente tradotto nelle due istruzioni: movl $2, %eax e addl $5, %eax.
Scrivere un file
expr.s che contiene la traduzione IA32 della funzione C
expr. Compilare il programma insieme al main di prova, ricordando che il valore restituito da una funzione per convenzione è contenuto nel registro A:
#include <stdio.h>
short expr
();
// prototipo per la funzione definita nel modulo es1.s
int main
() {
short z = expr
();
printf("expr() -> %hd\n", z
);
// stampa contenuto variabile z
return 0;
}
Per compilare il programma, usare
gcc -m32 expr_main.c expr.s -o expr, che genera un eseguibile
expr.
Esercizio 2: accesso a parametri interi di una funzione
Si traduca in Assembly IA32 la seguente funzione C, scrivendo un modulo
quadrato.s:
int quadrato(int x) {
return x*x;
}
Usare il seguente programma di prova:
#include <stdio.h>
int quadrato
(int x
);
int main
() {
printf("quadrato(8)=%d\n", quadrato
(8));
// deve stampare 64
return 0;
}
Esercizio 3: operatori bit a bit
Si traduca in Assembly IA32 la seguente funzione C, scrivendo un modulo
pari.s:
int pari(unsigned x) {
return !(x & 1);
}
- Suggerimento: usare le istruzioni IA32 NOT e AND.
Usare il seguente programma di prova:
#include <stdio.h>
int pari
(unsigned x
);
int main
() {
printf("pari(81)=%d\n", pari
(81));
// deve stampare 0
printf("pari(722)=%d\n", pari
(722));
// deve stampare 1
return 0;
}
Esercizio 4: parametri con meno di 32 bit
Si traduca in Assembly IA32 la seguente funzione C, scrivendo un modulo
diff.s:
char diff(char x, char y) {
return x - y;
}
Usare il seguente programma di prova:
#include <stdio.h>
char diff
(char x,
char y
);
int main
() {
char z = diff
(10,
20);
printf("%hd\n", z
);
// deve stampare -10
return 0;
}
Esercizio 5: Costrutto if..else: differenza in valore assoluto
Si traduca in Assembly IA32 la seguente funzione C che calcola il valore assoluto della differenza dei parametri, scrivendo un modulo
mod.s:
int mod(int x, int y) {
if (x>=y) return x-y;
else return y-x;
}
Si suggerisce di riscrivere dapprima il programma in una forma C equivalente in cui l'
if (...) istruzione viene rimpiazzato da un
if (...) goto. Scrivere un programma di prova per testare la funzione IA32.
Esercizio 6: accesso a parametri puntatore di una funzione
Si traduca in Assembly IA32 la seguente funzione C, scrivendo un modulo
raddoppia.s:
void raddoppia(int* p) {
*p = *p * 2;
}
Si tenga presente che l'istruzione
imul deve avere come operando destinazione necessariamente un registro. Usare il seguente programma di prova:
#include <stdio.h>
void raddoppia
(int* p
);
int main
() {
int x =
15;
raddoppia
(&x
);
printf("x=%d\n", x
);
// deve stampare 30
return 0;
}
Esercizio 7: costrutto if...else, puntatori
Si traduca in Assembly IA32 la seguente funzione C, scrivendo un modulo
cap.s:
void cap(short* x, short* y) {
if (*x>*y) *x = *y;
}
Si suggerisce di riscrivere dapprima il programma in una forma C equivalente in cui l'
if (...) istruzione viene rimpiazzato da un
if (...) goto. Scrivere un programma di prova per testare la funzione IA32.
Esercizio 8: array con indice costante
Si traduca in Assembly IA32 la seguente funzione C, scrivendo un modulo
get_second.s:
short get_second(short* v, int n) { // v è un array, n è la lunghezza dell'array
short a = -1;
if (n>=2) a=v[1];
return a;
}
Si suggerisce di riscrivere dapprima il programma in una forma C equivalente in cui l'
if (...) istruzione viene rimpiazzato da un
if (...) goto. Scrivere un programma di prova per testare la funzione IA32.
Esercizio 9: costrutto while: azzeramento di un array
Si traduca in Assembly IA32 la seguente funzione C, scrivendo un modulo
clear.s:
void clear(char* v, unsigned n) { // v è un array, n è la lunghezza dell'array
unsigned i=0;
while (i<n) v[i++]=0;
}
Si suggerisce di riscrivere dapprima il programma in una forma C equivalente in cui il
while viene rimpiazzato da un
if (...) goto. Scrivere un programma di prova per testare la funzione IA32.
Esercizio 10: costrutto while: azzeramento di un array - variante
Si traduca in Assembly IA32 la seguente funzione C, scrivendo un modulo
clear2.s:
void clear2(char* v, unsigned n) { // v è un array, n è la lunghezza dell'array
char* p=v+n;
while (v<p) *v++=0;
}
Si suggerisce di riscrivere dapprima il programma in una forma C equivalente in cui il
while viene rimpiazzato da un
if (...) goto. Scrivere un programma di prova per testare la funzione IA32.
Esercizio 11: calcolo lunghezza di una stringa
Si traduca in Assembly IA32 la seguente funzione C, scrivendo un modulo
mystrlen.s:
unsigned mystrlen(const char* s) { // s è una stringa terminata da un terminatore a zero
unsigned n = 0;
while (*s++) n++;
return n;
}
Si suggerisce di riscrivere dapprima il programma in una forma C equivalente in cui il
while viene rimpiazzato da un
if (...) goto. Scrivere un programma di prova per testare la funzione IA32.
Esercizio 12: costrutto for
Si traduca in Assembly IA32 la seguente funzione C, scrivendo un modulo
sum.s:
short sum(short* v, unsigned n) {
unsigned i;
short s = 0;
for (i=0; i<n; ++i) s += v[i];
return s;
}
Si ricordi che il valore di ritorno di una funzione è sempre a 32 bit per gli interi (
char e
short vengono quindi promossi a
int) e viene passato in
eax. Si suggerisce di riscrivere dapprima il programma in una forma C equivalente in cui il
for viene rimpiazzato da un
while, e poi il
while da un
if (...) goto. Scrivere un programma di prova per testare la funzione IA32.
Esercizio 13: somma di matrice
Si traduca in Assembly IA32 la seguente funzione C, scrivendo un modulo
matsum.s:
int matsum(int** v, int n) {
int i, j, s = 0;
for (i=0; i<n; ++i)
for (j=0; j<n; ++j)
s += v[i][j];
return s;
}
Si suggerisce di riscrivere dapprima il programma in una forma C equivalente in cui il
for viene rimpiazzato da un
while, e poi il
while da un
if (...) goto. Usare il seguente programma di prova:
#include <stdio.h>
#include <stdlib.h>
#define N 10
int matsum(int** v, int n);
int main() {
int i, j, **v = malloc(N*sizeof(int*));
for