Esame di Calcolatori Elettronici Appello del 5/6/'03 (Telecomunicazioni) Esercizio 1) Realizzare in Assembler GNU la seguente funzione (scrivere sul file es1.s ed eseguire): struct sru{ int aa[4]; char bb[8]; }; extern "C" sru ela(sru& s1, sru s2) { int i; sru ss; for (i=0; i<4; i++) { s1.aa[i]=s2.aa[i]; ss.aa[i]=s1.aa[i]+s2.aa[i]; ss.bb[i]=s1.bb[i]=s2.bb[i]+s2.bb[2]; } for (i=0; i<4; i++) { ss.bb[i+4]=s2.bb[i]+s2.bb[1]; s1.bb[i+4]=s2.bb[i]+s2.bb[3]; } return ss; } Esercizio 2) Realizzare quanto richiesto in C++ (scrivere sul file es2.cc ed eseguire). Siano date le seguenti dichiarazioni, contenute nel file cc.h: #include class albin { struct elem {char* cognome; int quanti; elem* l; elem* r;}; elem* root; elem* ins(elem*, char[], int, int); void sommaal(elem*,int,int&); void stampaal(elem*); void salvaal(elem* , ofstream&, int, int ); public: albin(){root=0;} void insert(char[], int); void stampa(); int somma(int ); void salva(char [], int, int); }; La classe albin realizza un albero binario ordinato in modo tale che facendo una visita dell'albero in ordine simmetrico i campi cognome risultino ordinati per numero crescente di caratteri che li compongono e, in caso di campi cognome con lo stesso numero di caratteri, i campi risultino ordinati per valori alfabeticamente crescenti. Realizzare: 1) la funzione membro insert(), che inserisce un nuovo elemento nell'albero mantenendo l'ordinamento; nella realizzazione della funzione si consiglia di definire ed utilizzare la funzione privata ins(); 2) la funzione membro somma() che restituisce la somma dei campi quanti di tutti gli elementi il cui numero di caratteri del campo cognome è multiplo del numero passato come argomento alla funzione; nella realizzazione della funzione si consiglia di definire ed usare la funzione privata sommaal(); 3) la funzione membro salva() che salva sul file il cui nome è passato come primo parametro tutti gli elementi il cui campo cognome ha un numero di caratteri compreso (estremi inclusi) tra il secondo ed il terzo argomento della funzione; nella realizzazione della funzione si consiglia di definire la funzione privata salva(). La funzione membro stampa() stampa su uscita standard gli elementi dell'albero visitando l'albero in ordine simmetrico. La funzione stampa() è 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 tre strutture s1, s2 e s3 di tipo sru, inizializzando i campi aa e bb della struttura s2 con gli interi da 0 a 3, e i caratteri da '0' a '7', rispettivamente; 2. chiama la funzione ela() passandole s1 e s2 e assegnando la struttura restituita a s3; 3. stampa su uscita standard s1 e s3; 4. dichiara due alberi alb e alb1; 5. apre il file di nome "ingr.txt" in lettura e, fino a raggiungere la fine del file, legge una stringa di al massimo 20 caratteri ed un numero intero e li inserisce nell'albero alb; 6. inserisce nell'albero alb la stringa "Neri" e l'intero s3.aa[2]; 7. stampa l'albero su uscita standard; 8. chiama la funzione somma() su alb passandole l'intero 2 come parametro e stampa il risultato su uscita standard; 9. chiama la funzione salva() passandole la stringa "temp.txt" e gli interi 4 e 6 come parametri; 10. apre il file di nome "temp.txt" in lettura e, fino a raggiungere la fine del file, legge una stringa di al massimo 20 caratteri ed un numero intero e li inserisce nell'albero alb1; 11. stampa l'albero alb1 su uscita standard. Esame di Calcolatori Elettronici Appello del 5/6/2003 - Soluzioni # file es1.s .text .globl _ela _ela: pushl %ebp movl %esp,%ebp subl $28,%esp pushl %edi pushl %esi pushl %ebx movl 12(%ebp),%edx movl $0,-4(%ebp) for1: cmpl $4,-4(%ebp) jl corpo1 jmp finefor1 corpo1: movl -4(%ebp),%ecx movl 16(%ebp,%ecx,4),%esi #s1.aa[i]=s2.aa[i] movl %esi,(%edx,%ecx,4) addl %esi,%esi #ss.aa[i]=s1.aa[i]+s2.aa[i] movl %esi,-28(%ebp,%ecx,4) movb 34(%ebp),%bl #s1.bb[i]=s2.bb[i]+s2.bb[2] addb 32(%ebp,%ecx),%bl movb %bl, 16(%edx,%ecx) movb %bl,-12(%ebp,%ecx) #ss.bb[i]=s1.bb[i] incl -4(%ebp) jmp for1 finefor1: movl $0,-4(%ebp) for2: cmpl $4,-4(%ebp) jl corpo2 jmp finefor2 corpo2: movl -4(%ebp),%ecx movb 33(%ebp),%bl #ss.bb[i+4]=s2.bb[i]+s2.bb[1] addb 32(%ebp,%ecx),%bl movb %bl, -8(%ebp,%ecx) movb 35(%ebp),%bl #s1.bb[i+4]=s2.bb[i]+s2.bb[3] addb 32(%ebp,%ecx),%bl movb %bl, 20(%edx,%ecx) incl -4(%ebp) jmp for2 finefor2: movl 8(%ebp),%eax movl %eax,%edi leal -28(%ebp),%esi cld movl $6,%ecx rep movsl popl %ebx popl %esi popl %edi leave ret Esercizio 2 //file cc.h esistente #include class albin { struct elem {char* cognome; int quanti; elem* l; elem* r;}; elem* root; elem* ins(elem*, char[], int, int); void sommaal(elem*,int,int&); void stampaal(elem*); void salvaal(elem* , ofstream&, int, int ); public: albin(){root=0;} void insert(char[], int); void stampa(); int somma(int ); void salva(char [], int, int); }; //file ccob.cc esistente void albin::stampaal(elem* p) { if (p!=0) { stampaal(p->l); cout << p->cognome << '\t' << p-> quanti << endl; stampaal(p->r); } } void albin::stampa() { if (root!=0) stampaal(root); } //file es2.cc #include #include "cc.h" void albin :: insert(char cognome[], int num) { root=ins(root,cognome, num, strlen(cognome)); } albin::elem* albin::ins(elem* p, char cognome[], int num, int lun) { if (p==0) { p=new elem; p->quanti=num; p->l=0; p->r=0; p->cognome=new char[strlen(cognome)+1]; strcpy(p->cognome,cognome); } else { if (strlen(p->cognome)>lun || strlen(p->cognome)==lun && strcmp(p->cognome,cognome)>=0) p->l=ins(p->l,cognome,num,lun); else p->r=ins(p->r,cognome,num,lun); } return p; } int albin::somma(int num) { int tot=0; sommaal(root,num,tot); return tot; } void albin::sommaal(elem* p,int num,int& tot) { int temp; if (p!=0) { sommaal(p->l,num,tot); temp=strlen(p->cognome); if (temp>=num && !(temp%num)) tot+=p->quanti; sommaal(p->r,num,tot); } } void albin::salvaal(elem* p, ofstream& out, int min, int max) { int temp=strlen(p->cognome); if (p!=0 && temp >= min) salvaal(p->l,out,min,max); if (temp>=min && temp <=max) out << p->cognome << ' '<< p->quanti << endl; if (p!=0 && temp<=max) salvaal(p->r,out,min,max); } void albin::salva(char nomefile[], int min, int max) { ofstream out(nomefile); if (!out) { cerr << "Errore nell'apertura del file " << nomefile << endl; exit(1); } salvaal(root,out,min, max); } Esercizio 3 //file es3.cc #include #include "cc.h" struct sru{ int aa[4]; char bb[8]; }; extern "C" sru ela(sru& s1, sru s2); void stampa(sru s) { cout << "aa[]="; for (int i=0; i<4; i++) cout << s.aa[i] << '\t'; cout << endl; cout << "bb[]="; for (int i=0; i<8; i++) cout << s.bb[i] << '\t'; cout << endl; } void main() { sru s1, s2={{0,1,2,3}, {'0','1','2','3','4','5','6','7'}}, s3; s3=ela(s1,s2); cout << "Stampa della struttura s1 dopo la chiamata della funzione" << endl; stampa(s1); cout << "Stampa della struttura s3 dopo la chiamata della funzione" << endl; stampa(s3); albin alb; char leggi [20]; int num; ifstream in("ingr.txt"); if (!in) { cerr << "Errore nell'apertura del file ingr.txt " << endl; exit(1); } while (in >> leggi >> num) alb.insert(leggi,num); alb.insert("Neri",s3.aa[2]); cout << "Stampa dell'albero alb" << endl; alb.stampa(); cout << "Somma dei campi quanti " << alb.somma(2) << endl; alb.salva("temp.txt",4,6); in.close(); in.open("temp.txt"); if (!in) { cerr << "Errore nell'apertura del file temp.txt " << endl; exit(1); } albin alb1; while (in >> leggi >> num) alb1.insert(leggi,num); cout << "Stampa dell'albero alb1 " << endl; alb1.stampa(); }