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