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

Esercitazione 1 - 20 ottobre 2015 (90 min)


Questionario

Prima di iniziare l'esercitazione, si prega di riempire il questionario anonimo sul primo anno del corso di laurea in Ingegneria Informatica e Automatica.


Configurazione

Aula 15 (canale provenienza AO)

In quest'aula lavoreremo con l'installazione nativa di Linux Debian.

Per questa prima esercitazione, è necessario installare le librerie gcc a 32 bit. Seguire i seguenti passi:

Creare una directory di lavoro sc1516 e posizionarsi nella directory creata come segue:

$ mkdir /home/studente15/Scrivania/sc1516
$ cd /home/studente15/Scrivania/sc1516


Aula 16 (canale provenienza PZ)

In quest'aula lavoreremo con Linux LXLE nella VM Oracle Virtualbox BIAR.

Per questa prima esercitazione, è necessario installare le librerie gcc a 32 bit. Seguire i seguenti passi:

Creare una directory di lavoro sc1516 e posizionarsi nella directory creata come segue:

$ mkdir /home/biar/Desktop/sc1516
$ cd /home/biar/Desktop/sc1516



Primi passi

Creare un file dal nome hello.c:

$ touch hello.c
$ geany hello.c &


Il primo comando crea un file vuoto chiamato hello.c. Il secondo apre l'editor di testo geany. Si noti l'& alla fine della riga, che serve per lanciare il programma "in background". Se omettiamo l'& e geany non è già aperto, il terminale si blocca finché non viene chiuso geany. Osserviamo che usando la freccia su si riprendono comandi precedentemente inseriti nel terminale. Inoltre, con il tasto tabulazione (TAB) si ha autocompletamento dei nomi di file e directory nel terminale.


Esercizio 1 (compilazione separata file)

L'obiettivo dell'esercizio è sperimentare l'uso delle opzioni di gcc per la compilazione a stadi separati. Si immetta il seguente programma C di esempio nel file hello.c:

hello.c
#include <stdio.h>

int main() {
    printf("Hello World\n");
    return 0;
}


Si effettuino i seguenti passi (dopo ogni passo si esamini il contenuto della directory corrente con il comando ls):

Si noti l'opzione -m32 che serve per generare codice IA32 in un sistema operativo a 64 bit.


Esercizio 2 (espressioni)

Si traduca il seguente programma C in un modulo assembly IA32 es2.s:

int es2() {
    return 5*6-2*7-1;
}


Consultare il capitolo 4 della dispensa per una descrizione delle istruzioni IA32. Si ricordi che il valore di ritorno di una funzione è nel registro A e che è possibile usare liberamente come se fossero variabili solo i registri A, C e D. Si tenga presente inoltre che l'istruzione prodotto imul deve avere come destinazione necessariamente un registro.


# Programma C originale:
# int es2() {
#    return 5*6-2*7-1;
# }

# Programma C equivalente:
# int es2() {
#    int a = 5; // usiamo nomi delle variabili corrispondenti ai registri che useremo in IA32
#    a = a * 6;
#    int c = 2;
#    c = c * 7;
#    a = a - c;
#    a = a - 1;
#    return a;
# }

.globl es2

es2:
	...
	ret


Si consideri il seguente programma di prova:

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

int es2(); // prototipo della funzione definita in es2.s

int main() {
    int x = es2();
    printf("x=%d\n", x); // deve stampare x=15
    return 0;
}


Si compili il programma con:

$ gcc -m32 es2-main.c es2.s -o es2


notare che la riga di comando contiene tutti i moduli necessari al funzionamento del programma (sia es2-main.c che es2.s). Si esegua poi il programma con:

$ ./es2



Esercizio 3 (espressioni)

Si traduca il seguente programma C in un modulo assembly IA32 es3.s:

int es3() {
    return 3*(5+6)-2*7;
}


Si scriva un main di prova e si testi il funzionamento del programma come fatto nell'esercizio 1.


Esercizio 4 (accesso ai parametri)

Si traduca il seguente programma C in un modulo assembly IA32 es4.s:

int es4(int x) {
    return x+10;
}



Si scriva un main di prova e si testi il funzionamento del programma.


Esercizio 5 (accesso ai parametri)

Si traduca il seguente programma C in un modulo assembly IA32 es5.s:

int es5(int x, int y, int z) {
    return 2*x-3*y+z;
}


Si scriva un main di prova e si testi il funzionamento del programma.


Esercizio 6 (accesso ai parametri)

Si traduca il seguente programma C in un modulo assembly IA32 es6.s:

short es6(short x, short y) {
    return x*x + y*y;
}


Si scriva un main di prova e si testi il funzionamento del programma.


Esercizio 7 (uso dei puntatori)

Si traduca il seguente programma C in un modulo assembly IA32 es7.s:

int es7(int* x) {
    return *x + 1;
}


Si consideri il seguente main di prova e si testi il funzionamento del programma:

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

int es7(int* x);

int main() {
    int a = 10;
    int b = es7(&a);
    printf("a=%d, b=%d\n", a, b); // deve stampare: a=10, b=11
    return 0;
}



Esercizio 8 (uso dei puntatori)

Si traduca il seguente programma C in un modulo assembly IA32 es8.s:

void init(int* p) {
    p[0] = 30;
    p[1] = 20;
    p[2] = 10;
}


Si consideri il seguente main di prova e si testi il funzionamento del programma:

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

void init(int* v);

int main() {
    int v[3] = {-1, -2, -3};
    init(v);
    printf("v[0]=%d, v[1]=%d, v[2]=%d\n", v[0], v[1], v[2]); // deve stampare: v[0]=30, v[1]=20, v[2]=10
    return 0;
}


Soluzioni

Le soluzioni dell'esercitazione sono qui (file zip, 5.3 KB).
Valid XHTML 1.0 Transitional :: Valid CSS :: Powered by WikkaWiki
Page was generated in 0.0758 seconds