Esame di Calcolatori Elettronici Appello del 10/7/'02 (Telecomunicazioni) Esercizio 1) Realizzare in Assembler GNU la seguente funzione (scrivere sul file es1.s ed eseguire): struct r1 { int a; int v1[4]; int b; }; struct r2 { int v2[4]; int c; }; extern "C" r1 fff (r1 sa, r2& sb) { r1 rr; for (int i = 0; i < 4; i++) rr.v1[i] = sa.v1[i] + sb.v2[i] - sa.a; for (int i = 0; i < 4; i++) sb.v2[3-i] = sa.v1[i] + sa.b + sb.c; rr.a = rr.b = sa.v1[0]; return rr; } Esercizio 2) Realizzare quanto richiesto in C++ (scrivere sul file es2.cc ed eseguire). Siano date le seguenti dichiarazioni, contenute nel file cc.h: class tabella { struct elem { char* key; int val;}; int size; elem* table; public: tabella(int n) { size = n; table = new elem[size]; for (int i = 0; i < size; i++) { table[i].key =0; table[i].val=0; } } void build(const char []); void print(); void compatta(); void cancella(int ); }; La classe tabella realizza una tabella in cui il campo key è una stringa ed il campo informazione è un intero. La tabella è implementata da un vettore. Realizzare: 1) la funzione membro build(), che, prima, per tutti gli elementi il cui campo key è diverso da 0 (si supponga che la tabella sia compatta verso gli indici minori), cancella il campo key e pone a zero i campi key e val; quindi apre in lettura il file il cui nome è passato come parametro, e ripete le azioni seguenti fino ad arrivare o alla fine del file o a riempire la tabella: a) legge una stringa (di massimo 10 caratteri) ed un numero intero; b) usa la stringa ed il numero intero per inizializzare il primo elemento della tabella che ha il campo key uguale a zero (la tabella è compatta verso gli indici minori); se la tabella diviene piena, stampa su uscita standard un messaggio di errore (senza uscire); 2) la funzione membro cancella(), che, pone a zero il campo val e, dopo averlo cancellato, il campo key dell'elemento il cui indice è passato come parametro; se l'indice non è valido o il campo key è 0, stampa un messaggio di errore sullo standard error ed esce; 3) la funzione membro compatta() che compatta gli elementi contenuti nella tabella verso gli indici minori (in pratica, scandendo la tabella a partire dall'indice 0, elementi con campo key diverso da 0 non devono essere separati tra di loro da elementi con campo key uguale a 0). La funzione print() stampa su uscita standard tutti gli elementi della tabella (se il campo key è nullo stampa il carattere ?'). La funzione print() è implementata nel file ccob.o. Esercizio 3) Realizzare quanto richiesto in C++ (scrivere sul file es3.cc ed eseguire). Scrivere un programma che: 1. dichiara una struttura ssa di tipo r1 inizializzando i campi a, v1, e b con l'intero 0, gli interi da 0 a 3, e l'intero 15, rispettivamente; 2. dichiara una struttura ssb di tipo r2 inizializzando i campi v2 e c con gli interi da 10 a 13, e l'intero 20; 3. dichiara una struttura ssc di tipo r1; 4. chiama la funzione fff() passandole come parametri ssa e ssb ed assegnando la struttura restituita a ssc; 5. stampa su uscita standard ssb e ssc; 6. dichiara una tabella tab di 6 elementi; 7. chiama la funzione build() su tab passandole la costante stringa "ingr" come parametro; 8. stampa la tabella su uscita standard; 9. cancella i tre elementi individuati, rispettivamente, dagli indici ssc.a, 2 e 3; 10. stampa su uscita standard la tabella; 11. compatta la tabella; 12. stampa su uscita standard la tabella. Esame di Calcolatori Elettronici Appello del 10/7/'02 (Telecomunicazioni) Soluzioni Esercizio 1 #file es1.s .text .globl _fff _fff: pushl %ebp movl %esp,%ebp subl $28,%esp pushl %edi pushl %esi pushl %ebx pushl %ecx movl 36(%ebp),%ebx movl $0,-28(%ebp) for1: cmpl $4,-28(%ebp) jl corpo1 jmp fine1 corpo1: movl -28(%ebp),%ecx movl 16(%ebp,%ecx,4),%edi #primo for addl (%ebx,%ecx,4),%edi subl 12(%ebp),%edi movl %edi,-20(%ebp,%ecx,4) incl -28(%ebp) jmp for1 fine1: movl $0,-28(%ebp) for2: cmpl $4,-28(%ebp) #secondo for jl corpo2 jmp fine2 corpo2: movl $3,%ecx subl -28(%ebp),%ecx movl -28(%ebp),%esi movl 16(%ebp,%esi,4),%edi addl 32(%ebp),%edi addl 16(%ebx),%edi movl %edi,(%ebx,%ecx,4) incl -28(%ebp) jmp for2 fine2: movl 16(%ebp),%edi movl %edi,-4(%ebp) #rr.a=rr.b=sa.v1[0] movl %edi,-24(%ebp) movl 8(%ebp),%eax #restituzione della struttura rr leal -24(%ebp),%esi movl %eax,%edi cld movl $6,%ecx rep movsl popl %ecx popl %ebx popl %esi popl %edi leave ret Esercizio 2 //file cc.h esistente class tabella { struct elem { char* key; int val;}; int size; elem* table; public: tabella(int n) { size = n; table = new elem[size]; for (int i = 0; i < size; i++) { table[i].key =0; table[i].val=0; } } void build(const char []); void print(); void compatta(); void cancella(int ); }; //file ccob.cc esistente #include "cc.h" #include "cc.h" #include void tabella::print() { for (int i=0; (i #include #include #include #include "cc.h" #include void tabella::build(const char nome[]) { if (table!=0) { for (int i = 0; i < size && table[i].key!=0; i++) { delete[] table[i].key; table[i].key=0; table[i].val=0; } } ifstream in(nome); if (!in) { cerr << "errore nell'apertura del file " << nome << endl; exit(1); } int i=0, val; char parola[10]; while (in>>parola && in >>val && i=size || index<0 || table[index].key==0) { cerr << "Indice non valido " << endl; exit(1); } delete[] table[index].key; table[index].key=0; table[index].val=0; } void tabella::compatta() { int i,j; for (i=0;i #include "cc.h" struct r1 { int a; int v1[4]; int b; }; struct r2 { int v2[4]; int c; }; extern "C" r1 fff (r1 sa, r2& sb); void stampa(const r1& s) { cout << "a = " << s.a << endl; cout << "v1[]= "; for (int i=0; i<4; i++) cout << s.v1[i] << ' '; cout << endl; cout << "b = " << s.b << endl; } void stampa(const r2& s) { cout << "v2[]= "; for (int i=0; i<4; i++) cout << s.v2[i] << ' '; cout << endl; cout << "c = " << s.c << endl; } void main() { int i; r1 ssa = {0, {0,1,2,3}, 15}; r2 ssb = {{10,11,12,13}, 20}; r1 ssc = fff(ssa, ssb); cout << "Stampa della struttura ssb di tipo r2 passata alla funzione " << endl; stampa(ssb); cout << "Stampa della struttura ssc di tipo r1 restituita dalla funzione" << endl; stampa(ssc); tabella tab(6); tab.build("ingr"); tab.print(); tab.cancella(ssc.a); tab.cancella(2); tab.cancella(3); tab.print(); tab.compatta(); tab.print(); }