Sistemi di Calcolo

Corso di Laurea in Ingegneria Informatica e Automatica - A.A. 2017-2018

HomePage | Avvisi | Diario lezioni | Programma | Materiale didattico | Esami | Forum | Login

Esercizi traduzione da C ad Assembly IA32 (A.A. 2016-17)


Si vedano le discussioni e le soluzioni sul forum. Alcuni esercizi sono risolti qui.

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.


Esercizio 2 (Invocazione funzione IA32 da programma C)

Provare il funzionamento della soluzione dell'Esercizio 1 considerandola parte di una funzione:

es2.c
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:

es2_main.c
#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:

quadrato_main.c
#include <stdio.h>

int quadrato(int x);

int main() {
    printf("quadrato(8)=%d\n", quadrato(8)); // deve stampare 64
    return 0;
}


Esercizio 4 (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 5 (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 6 (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 7 (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:

raddoppia_main.c
#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 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:

matsum.c
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:

matsum-main.c
#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 (i=0; i<N; ++i) {
        v[i] = malloc(N*sizeof(int));
        for (j=0; j<N; ++j) v[i][j] = 2;
    }
    int s = matsum(v, N);
    printf("somma=%d (corretto: 200)\n", s);
    for (i=0; i<N; ++i) free(v[i]);
    return 0;
}


Esercizio 14 (Frequenza caratteri)

Scrivere una funzione C void charfreq(const char* text, unsigned* freq) che calcola per ogni carattere ASCII il suo numero di occorrenze nella stringa text. Il risultato va scritto nell'array freq, che si assume abbia 256 celle. Tradurre poi la funzione scritta in assembly IA32, scrivendo un modulo charfreq.s. Si usi il seguente programma di prova:

charfreq-main.c
#include <stdio.h>