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 il seguente frammento C, mantenendo la variabile x nel registro A:
short x=(20-2)*(7+3)+2*(10-7);
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.
Esercizio 2 (Invocazione funzione IA32 da programma C)
Provare il funzionamento della soluzione dell'Esercizio 1 considerandola parte di una funzione:
short es2() {
short x=(20-2)*(7+3)+2*(10-7);
return x;
}
Scrivere un file
es2.s che contiene la traduzione IA32 della funzione C
es2. 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 es2
();
// prototipo per la funzione definita nel modulo es2.s
int main
() {
short z = es2
();
printf("es2() -> %hd\n", z
);
// stampa contenuto variabile z
return 0;
}
Per compilare il programma, usare
gcc es2_main.x es2.s -o es2, che genera un eseguibile
es2.
Esercizio 3 (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 4 (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 5 (Costrutto if: valore assoluto)
Si traduca in Assembly IA32 la seguente funzione C, scrivendo un modulo
abs.s:
int abs(int x) {
if (x<0) x = -x;
return 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 (Costrutto if...else: valore assoluto)
Si traduca in Assembly IA32 la seguente funzione C, scrivendo un modulo
abs2.s:
int abs2(int x) {
if (x>=0) return x;
else return -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 7 (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 8 (Costrutto if)
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.