Esame di Calcolatori Elettronici Appello del 20/6/'02 (Telecomunicazioni) Esercizio 1) Realizzare in Assembler GNU la seguente funzione (scrivere sul file es1.s ed eseguire): struct ss { int v1[3]; char a; int v2[3];}; extern "C" ss fss(char c, int v[], ss sa) { ss ris; int i; ris.a = sa.a + c; for (i=0; i<3; i++) ris.v1[i] = sa.v1[i]+v[i]; for (i=0; i<3; i++) ris.v2[i] = sa.v2[i]+v[3]; return ris; } 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 {int index; int ris[3]; int somma; elem* l; elem* r;}; elem* root; void salvaal(ofstream&,elem*,int,int); elem* ins(elem* , int , const int [],int ); void stampaal(elem*); public: albin(){root=0;} void salva(const char[], int, int); void build(const char []); void insert(int , const int []); void stampa(); }; La classe albin implementa un albero binario in cui ogni nodo contiene un intero index, un vettore ris di 3 interi ed un intero somma, che contiene la somma degli interi contenuti in ris. L'albero Š ordinato in modo tale che facendo una visita dell'albero in ordine simmetrico i campi somma risultano ordinati per valori decrescenti. Realizzare: 1) la funzione membro insert(), che inserisce un nuovo elemento nell'albero mantenendo l'albero ordinato; al campo index ed agli interi del campo ris del nuovo elemento sono assegnati l'intero passato come primo parametro e gli interi del vettore passato come secondo parametro. Nella definizione della funzione utilizzare la funzione privata ins() (da definire); 2) la funzione membro build() che apre il file il cui nome Š passato come parametro e ripete le azioni seguenti fino alla fine del file: legge quattro interi e chiama la funzione insert() passandole il primo intero come primo parametro ed un array con gli altri tre interi come secondo parametro; 3) la funzione salva() che salva sul file il cui nome Š passato come primo parametro il campo index ed il campo ris (separando gli elementi del campo ris con un simbolo di tabulazione) dei nodi che hanno tutti gli interi contenuti in ris non inferiori all'intero passato come primo parametro ed il campo somma non inferiore all'intero passato come secondo parametro. Nella definizione della funzione utilizzare la funzione privata salvaal() (da definire). La funzione stampa() stampa su uscita standard tutti gli elementi del vettore. 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 una struttura sa di tipo ss inizializzando i campi v1, a, e v2 con gli interi da 1 a 3, il carattere 'F' e gli interi da 4 a 6, rispettivamente; 2. dichiara una struttura sb di tipo ss; 3. dichiara un vettore v di 4 interi inizializzandolo con gli interi da 12 a 15; 4. chiama la funzione fss() passandole il carattere '0', il vettore v e la struttura sa ed assegnando la struttura restituita a sb; 5. stampa su uscita standard la struttura sb; 6. dichiara due alberi al e al1; 7. chiama la funzione build() su al passandole la stringa "ingr"; 8. chiama la funzione insert() su al passandole sb.v1[0] e sb.v2 come primo e secondo parametro; 9. chiama la funzione insert() su al passandole sb.v1[1] e sb.v2 come primo e secondo parametro; 10. stampa su uscita standard al; 11. salva sul file di nome "temp" gli elementi dell'albero al che hanno tutti gli interi nel campo ris non inferiori a 15 e il campo somma non inferiore a 54; 12. chiama la funzione build() su al1 passandole la stringa "temp"; 13. stampa su uscita standard l'albero al1. Esame di Calcolatori Elettronici Appello del 20/6/'02 (Telecomunicazioni) Soluzioni Esercizio 1 #file es1.s .text .global _fss _fss: pushl %ebp movl %esp,%ebp subl $32,%esp #spazio variabili locali pushl %edi pushl %esi pushl %ebx pushl %ecx pushl %edx movl 16(%ebp),%edx #ind. vettore v in edx movb 12(%ebp),%bl #sa.a in bl addb 32(%ebp),%bl #sa.a + c in bl movb %bl, -16(%ebp) #ris.a=sa.a+c movl $0,-32(%ebp) for1: cmpl $3,-32(%ebp) #primo for jl corpo1 jmp fine1 corpo1: movl -32(%ebp),%ecx movl 20(%ebp, %ecx,4),%ebx #sa.v1[i] in ebx addl (%edx,%ecx,4), %ebx #sa.v1[i]+v[i] in ebx movl %ebx, -28(%ebp,%ecx,4) #ris.v1[i]=sa.v1[i]+v[i] incl -32(%ebp) jmp for1 fine1: movl $0,-32(%ebp) for2: cmpl $3,-32(%ebp) #secondo for jl corpo2 jmp fine2 corpo2: movl -32(%ebp),%ecx movl 36(%ebp, %ecx,4),%ebx #sa.v2[i] in ebx addl 12(%edx), %ebx #sa.v2[i]+v[3] in ebx movl %ebx, -12(%ebp,%ecx,4) #ris.v2[i]=sa.v2[i]+v[3] incl -32(%ebp) jmp for2 fine2: movl 8(%ebp), %eax #return ris movl %eax,%edi leal -28(%ebp),%esi cld movl $7,%ecx rep movsl popl %edx popl %ecx popl %ebx popl %esi popl %edi leave ret Esercizio 2 //file cc.h esistente #include class albin { struct elem {int index; int ris[3]; int somma; elem* l; elem* r;}; elem* root; void salvaal(ofstream&,elem*,int,int); elem* ins(elem* , int , const int [],int ); void stampaal(elem*); public: albin(){root=0;}; void salva(const char[], int,int); void insert(int , const int []); void stampa(); void build(const char []); }; //file ccob.cc esistente #include "cc.h" void albin::stampa() { stampaal(root); cout << endl << endl; } void albin::stampaal(elem* p) { if (p!=0) { stampaal(p->l); cout << "Index = " << p->index <<'\t'; cout << "v[] = "; for (int i=0; i<3; i++) cout << p->ris[i] << '\t'; cout << "Somma = " << p->somma << endl << endl; stampaal(p->r); } } //file es2.cc #include "cc.h" #include #include #include #include void albin :: insert(int id, const int v[]) { int somma=0; for (int i=0; i<3; i++) somma+=v[i]; root=ins(root,id,v,somma); } albin::elem* albin :: ins(elem* p, int id, const int v[],int somma) { if (p==0) { p=new elem; p->index=id; for (int i=0; i<3; i++) p->ris[i]=v[i]; p->somma=somma; p->l=0; p->r=0; } else if (p->somma <= somma) p->l=ins(p->l,id,v,somma); else p->r=ins(p->r,id,v,somma); return p; } void albin::salva(const char nome[], int soglia1, int soglia2) { ofstream out(nome); if (!out) { cerr << "Errore nell'apertura del file " << nome << endl; exit(1); } salvaal(out,root, soglia1, soglia2); } void albin::salvaal(ofstream& out, elem* p,int soglia1, int soglia2) { if (p!=0) { bool ok=true; for (int i=0; i<3 && ok; i++) if (p->ris[i]sommal, soglia1, soglia2); else { salvaal(out, p->l, soglia1, soglia2); salvaal(out, p->r, soglia1, soglia2); } if (p->somma>=soglia2 && ok) { out << p->index << '\t'; for (int i=0; i<3; i++) out << p->ris[i] << '\t'; } } } void albin::build(const char nome[]) { ifstream in(nome); if (!in) { cerr << "Errore nell'apertura del file " << nome << endl; exit(1); } int vv[3]; int index; while (in>>index) { for (int i=0; i<3 && in>>vv[i]; i++); insert(index,vv); } } Esercizio 3 //file es3.cc #include "cc.h" struct ss { int v1[3]; char a; int v2[3]; }; extern "C" ss fss(char c, int v[], ss sa); void stampa(const ss& s) { cout << "v1[] =\t"; for (int i=0; i<3; i++) cout << s.v1[i] << '\t'; cout << endl << "a =\t" << s.a << endl << "v2[] =\t"; for (int i=0; i<3; i++) cout << s.v2[i] << '\t'; cout << endl << endl; } void main() { ss sa={{1,2,3},'F',{4,5,6}},sb; int v[]={12,13,14,15}; sb=fss('0',v,sa); cout << "Stampa della struttura sb dopo la chiamata alla funzione " << endl; stampa(sb); albin al,al1; al.build("ingr"); al.insert(sb.v1[0],sb.v2); al.insert(sb.v1[1],sb.v2); cout << "Stampa dell'albero al " << endl; al.stampa(); al.salva("temp",15,54); al1.build("temp"); cout << "Stampa dell'albero al1 " << endl; al1.stampa(); }