Esame di Calcolatori Elettronici Appello del 11/9/'02 (Telecomunicazioni) Esercizio 1) Realizzare in Assembler GNU la seguente funzione (scrivere sul file es1.s ed eseguire): struct ss {int v[4]; int ii; char cc[8];}; extern "C" ss f(ss& ss1, ss ss2) { ss ss3; int i; for (i=0; i<4; i++) { ss1.v[i]=ss2.v[i]+ss2.ii; ss3.v[i]=ss1.v[i]+ss2.ii; ss3.cc[i]=ss2.cc[i]; ss1.cc[i+4]=ss2.cc[i]; ss1.cc[i]=ss2.cc[i+4]; ss3.cc[i+4]=ss2.cc[i+1];} ss1.ii=(int)ss2.cc[0]; ss3.ii=(int)ss2.cc[3]; return ss3; } 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 pila { struct elem { char* key; int val; elem* pun;}; elem* p0; public: pila() { p0=0;} pila (const pila &); void print(); void push (const char [], int); bool pop (char*& c, int& ); }; La classe pila realizza una pila utilizzando una lista per la memorizzazione dei dati. La cima della pila è puntata dal membro p0 della classe e coincide con la testa della lista. Ogni elemento contenuto nella pila è costituito da una stringa indirizzata dal campo key e da un numero intero individuato dal campo val. Realizzare: 1) il costruttore di copia pila(), che costruisce la nuova pila ricopiando tutti gli elementi della pila passata come parametro; 2) la funzione membro push(), che inserisce in cima alla pila la stringa ed il numero intero passati come parametri (la stringa deve essere ricopiata); 3) la funzione membro pop(), che estrae l'elemento in cima alla pila e restituisce la stringa individuata dal campo key e l'intero val dell'elemento estratto utilizzando, rispettivamente, il primo e secondo parametro della funzione; se la pila è vuota la funzione restituisce false; altrimenti restituisce true. Si ricorda che il tipo bool è un tipo predefinito che può assumere i valori true e false. La funzione print() stampa su uscita standard tutti gli elementi contenuti nella pila. 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 ss1 di tipo ss; 2. dichiara una struttura ss2 di tipo ss inizializzando il campi v con gli interi da 0 a 3, il campo ii con l'intero 10 ed il campo cc con i caratteri da 'a' a 'h', rispettivamente; 3. dichiara una struttura ss3 di tipo ss; 4. chiama la funzione f() passandole ss1 e ss2 come primo e secondo argomento, rispettivamente, ed assegnando la struttura restituita a ss3; 5. stampa su uscita standard le strutture ss1 e ss3; 6. dichiara un oggetto pp1 di classe pila; 7. apre il file di nome "ingr" in lettura e fino a raggiungere la fine del file legge una stringa (al massimo di 10 caratteri) ed un numero intero e li inserisce in cima alla pila pp1; 8. stampa su uscita standard la pila pp1; 9. estrae dalla pila un elemento e stampa la stringa e l'intero contenuti nell'elemento su uscita standard; 10. estrae dalla pila un altro elemento e stampa la stringa e l'intero contenuti nell'elemento su uscita standard; 11. dichiara un oggetto pp2 di classe pila inizializzandolo a pp1; 12. inserisce in cima alla pila pp2 la stringa "pippo" e l'intero ss3.ii; 13. inserisce in cima alla pila pp2 la stringa "pluto" e l'intero ss1.ii; 14. stampa su uscita standard la pila pp2. Esame di Calcolatori Elettronici Appello del 11/9/'02 (Telecomunicazioni) Soluzioni Esercizio 1 #file es1.s .text .global _f _f: pushl %ebp movl %esp,%ebp subl $32,%esp pushl %edi pushl %esi pushl %edx pushl %ecx movl $0,-4(%ebp) for: cmpl $4,-4(%ebp) jl corpo jmp fine corpo: movl 12(%ebp),%edx #indirizzo di ss1 in edx movl -4(%ebp),%ecx #i in ecx movl 16(%ebp,%ecx,4),%esi #ss1.v[i]=ss2.v[i]+ss2.ii; addl 32(%ebp),%esi movl %esi,(%edx,%ecx,4) addl 32(%ebp),%esi #ss3.v[i]=ss1.v[i]+ss2.ii; movl %esi,-32(%ebp,%ecx,4) movb 36(%ebp,%ecx),%al #ss3.cc[i]=ss2.cc[i]; movb %al, -12(%ebp,%ecx) movl %ecx,%esi #ss1.cc[i+4]=ss2.cc[i]; addl $4,%esi movb %al, 20(%edx,%esi) movb 36(%ebp,%esi),%al #ss1.cc[i]=ss2.cc[i+4]; movb %al, 20(%edx,%ecx) incl %ecx movb 36(%ebp,%ecx),%al #ss3.cc[i+4]=ss2.cc[i+1]; movb %al, -12(%ebp,%esi) incl -4(%ebp) jmp for fine: movl 12(%ebp),%edx #ss1.ii=(int)ss2.cc[0]; movsbl 36(%ebp),%esi movl %esi,16(%edx) movsbl 39(%ebp),%esi #ss3.ii=(int)ss2.cc[3]; movl %esi,-16(%ebp) movl 8(%ebp),%eax movl %eax,%edi leal -32(%ebp),%esi cld movl $7,%ecx rep movsl popl %ecx popl %edx popl %esi popl %edi leave ret Esercizio 2 //file cc.h esistente class pila { struct elem { char* key; int val; elem* pun;}; elem* p0; public: pila() { p0=0;} pila (const pila &); void print(); void push (const char [], int); bool pop (char*& c, int& ); }; //file ccob.cc esistente #include "cc.h" #include void pila::print() { for (elem* p=p0; p!=0; p=p->pun) cout << p->key << '\t' << p->val << endl; cout << endl; } //file es2.cc ##include "cc.h" #include #include pila::pila(const pila& s) { p0=0; elem* p1=0; for (elem* q=s.p0; q!=0; q=q->pun) { elem* p=new elem; p->key=new char [strlen(q->key)+1]; strcpy(p->key,q->key); p->val=q->val; p->pun=0; if (!p0) { p0=p; p1=p; } else { p1->pun=p; p1=p; } } } void pila::push (const char inkey [], int i) { elem* p=new elem; p->key=new char [strlen(inkey)+1]; strcpy(p->key,inkey); p->val=i; p->pun=p0; p0=p; } bool pila::pop (char*& key, int& i) { elem* p=p0; if (p0==0) return false; key=p->key; i=p->val; p0=p0->pun; delete p; return true; } Esercizio 3 //file es3.cc #include #include "cc.h" #include struct ss {int v[4]; int ii; char cc[8];}; extern "C" ss f(ss& ss1, ss ss2); void stampa(const ss& s) { cout << "v[] = "; for (int i=0; i<4; i++) cout << s.v[i] << ' '; cout << endl; cout << "ii = " << s.ii << endl; cout << "cc[] = "; for (int i=0; i<8; i++) cout << s.cc[i] << ' '; cout << endl << endl; } void main() { ss ss1, ss2={{0, 1, 2, 3}, 10, {'a','b','c','d','e','f','g','h'}}, ss3; ss3=f(ss1,ss2); cout << "Stampa della struttura ss1 " << endl; stampa(ss1); cout << "Stampa della struttura ss3 " << endl; stampa(ss3); pila pp1; ifstream in("ingr"); char leggi[10]; int val; char* risc; int risi; if (!in) { cerr << "Errore nell'apertura del file ingr " << endl; exit(1); } while (in>>leggi && in >> val) pp1.push(leggi,val); cout << "Stampa della pila pp1 " << endl; pp1.print(); pp1.pop(risc,risi); cout << "Elemento estratto dalla pila pp1"<< endl; cout << risc << '\t' << risi << endl<