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.