Esame di Calcolatori Elettronici Appello del 10/1/'03 (Telecomunicazioni) Esercizio 1) Realizzare in Assembler GNU la seguente funzione (scrivere sul file es1.s ed eseguire): struct stt {int v[5]; char c[10];}; extern "C" stt f(stt s1, stt* s2) { stt s3; int i; for (i=0; i<5; i++) { s2->v[i]=s1.v[i]*s1.v[i]; s3.v[i]=s1.v[i]+(int)s1.c[i]; s3.c[i]=s2->c[i]=s1.c[i]+2*s1.c[1]-s1.c[0]; } for (; i<10;i++) { s2->c[i]=s1.c[i]+2*s1.c[4]-s1.c[6]; s3.c[i]=s2->c[i]+(char)s1.v[0]; } return s3; } Esercizio 2) Realizzare quanto richiesto in C++ (scrivere sul file es2.cc ed eseguire). Siano date le seguenti dichiarazioni, contenute nel file cc.h: struct libro {char titolo[50]; char autore[20]; char genere[15]; int colloc; }; class archivio { struct elem {libro l; elem* next;}; int collocazione; elem* testa; public: archivio(){testa=0; collocazione=1;} void build(const char nome[]); void stampaTit(const char nomeAut[]); void stampa(); int conta(const char gen[], char iniz, char fine); bool rimuovi(int col); }; La classe archivio realizza un archivio di libri. Un libro è individuato attraverso il titolo, l'autore, il genere e la collocazione. L'archivio e' realizzato come una lista di libri ordinata per valori alfabeticamente crescenti degli autori. Il membro collocazione e' inizializzato ad 1 e e' incrementato ad ogni nuovo libro inserito. Realizzare: 1) la funzione membro build(), che apre in lettura il file passato come parametro e, fino a raggiungere la fine del file, ripete le azioni seguenti: legge dal file il titolo, l'autore ed il genere di un libro da inserire nell'archivio (al campo colloc viene assegnato il valore del membro collocazione che poi viene incrementato), ed inserisce il libro nell'archivio mantenendo l'ordinamento; 2) la funzione membro stampaTit(), che stampa su uscita standard i titoli dei libri scritti dall'autore il cui nome e' passato come argomento; 3) la funzione membro conta(), che restituisce il numero di libri scritti da autori i cui nomi iniziano con un carattere compreso tra i due caratteri iniz e fine passati come secondo e terzo parametro ed il cui genere e' uguale al genere passato come primo parametro; 4) la funzione membro rimuovi() che rimuove dall'archivio il libro la cui collocazione è passata come parametro alla funzione. La funzione membro stampa() stampa su uscita standard i libri contenuti nell'archivio. 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 s1 di tipo stt inizializzando il campo v con gli interi da 0 a 4, ed il campo c con i carattere da '0' a '9'; 2. dichiara due strutture s2 e s3 di tipo stt; 3. chiama la funzione f() passandole s1 e l'indirizzo di s2 come primo e secondo argomento, rispettivamente, ed assegnando la struttura restituita a s3; 4. stampa su uscita standard le strutture s2 e s3; 5. dichiara un'istanza ar di classe archivio; 6. chiama la funzione build() su ar passando come parametro il nome "ingr"; 7. stampa su uscita standard ar; 8. stampa su uscita standard i titoli dei libri scritti da Dante; 9. stampa su uscita standard il numero di libri di genere Romanzo scritti da autori il cui nome inizia con un carattere compreso tra 'A' e 'D'; 10. rimuove il libro con collocazione 3; 11. rimuove il libro con collocazione 1; 12. stampa su uscita standard ar. Esame di Calcolatori Elettronici Appello del 10/1/'03 - Soluzioni # file es1.s .text .global _f _f: pushl %ebp movl %esp,%ebp subl $36,%esp #spazio le variabili locali pushl %edi pushl %esi pushl %ebx pushl %ecx pushl %edx movl $0,-36(%ebp) for1: cmpl $5,-36(%ebp) #primo for jl corpo1 jmp finefor1 corpo1: movl 44(%ebp),%esi #indirizzo struttura puntata da s2 in esi movl -36(%ebp),%ecx movl 12(%ebp,%ecx,4),%eax #s2->v[i]=s1.v[i]*s1.v[i]; imull %eax movl %eax,(%esi,%ecx,4) movsbl 32(%ebp,%ecx),%ebx #s3.v[i]=s1.v[i]+(int)s1.c[i]; addl 12(%ebp,%ecx,4),%ebx movl %ebx,-32(%ebp,%ecx,4) movb 32(%ebp,%ecx), %bl #s3.c[i]=s2->c[i]=s1.c[i]+2*s1.c[1]-s1.c[0]; movb 33(%ebp), %al shlb $1,%al addb %al,%bl subb 32(%ebp),%bl movb %bl, 20(%esi,%ecx) movb %bl, -12(%ebp,%ecx) incl -36(%ebp) jmp for1 finefor1: for2: cmpl $10,-36(%ebp) #secondo for jl corpo2 jmp finefor2 corpo2: movl -36(%ebp),%ecx movb 32(%ebp,%ecx), %bl #s2->c[i]=s1.c[i]+2*s1.c[4]-s1.c[6]; movb 36(%ebp), %al shlb $1,%al addb %al,%bl subb 38(%ebp),%bl movb %bl, 20(%esi,%ecx) addb 12(%ebp),%bl #s3.c[i]=s2->c[i]+(char)s1.v[0]; movb %bl, -12(%ebp,%ecx) incl -36(%ebp) jmp for2 finefor2: movl 8(%ebp),%eax #return s3 leal -32(%ebp),%esi movl %eax,%edi cld movl $8,%ecx rep movsl popl %edx popl %ecx popl %ebx popl %esi popl %edi leave ret Esercizio 2 //file cc.h esistente struct libro {char titolo[50]; char autore[20]; char genere[15]; int colloc; }; class archivio { struct elem {libro l; elem* next;}; int collocazione; elem* testa; public: archivio(){testa=0; collocazione=1;} void build(const char nome[]); void stampaTit(const char nomeAut[]); void stampa(); int conta(const char gen[], char iniz, char fine); bool rimuovi(int col); }; //file ccob.cc esistente #include #include "cc.h" void archivio::stampa() { for (elem* p=testa; p!=0; p=p->next) cout << p->l.titolo << '\t' << p->l.autore << '\t' << p->l.genere << '\t' << p->l.colloc << endl; cout << endl; } //file es2.cc #include #include #include #include "cc.h" void archivio::build(const char nome[]) { ifstream in(nome); if (!in) { cerr << "Errore nell'apertura del file " << nome << endl; exit(1); } elem* r; while ((r=new elem) && in>>r->l.titolo) { in>>r->l.autore; in>>r->l.genere; r->l.colloc=collocazione++; if (!in) { cerr << "Errore nella lettura del file " << nome << endl; exit(1); } elem* p=testa,* q; for (q=p; q!=0 && strcmp(q->l.autore,r->l.autore)<0; q=q->next) p=q; r->next=q; if (q==testa) testa=r; else p->next=r; } delete r; } void archivio::stampaTit(const char nomeAut[]) { for (elem* p=testa; p!=0 && strcmp(p->l.autore,nomeAut)<=0; p=p->next) if (!strcmp(p->l.autore,nomeAut)) cout << p->l.titolo << endl; } bool archivio::rimuovi(int col) { elem* q,* p; bool trovato=false; for (p=q=testa; p!=0 && p->l.colloc!=col; p=p->next) q=p; if (p==0) return false; if (p==testa) testa=p->next; q->next=p->next; delete q; return true; } int archivio::conta(const char gen[], char iniz, char fine) { int conta=0; for (elem* p=testa; p!=0 && p->l.autore[0]<=fine; p=p->next) if (!strcmp(p->l.genere, gen) && p->l.autore[0]>=iniz) conta++; return conta; } Esercizio 3 /file es3.cc struct stt {int v[5]; char c[10];}; extern "C" stt f(stt s1, stt* s2); #include #include "cc.h" void stampa(const stt& s) { cout << "v[]= "; for (int i=0; i<5; i++) cout << s.v[i] << ' '; cout << endl << "c[]= "; for (int i=0; i<10; i++) cout << s.c[i] << ' '; cout << endl << endl; } void main() { stt s1={{0,1,2,3,4},{'0','1','2','3','4','5','6','7','8','9'}}; stt s2,s3; s3=f(s1, &s2); cout << "Stampa della struttura s2 dopo la chiamata alla funzione" << endl; stampa(s2); cout << "Stampa della struttura s3 dopo la chiamata alla funzione" << endl; stampa(s3); archivio ar; ar.build("ingr"); cout << "Stampa dell'archivio " << endl; ar.stampa(); cout << "Stampa i libri scritti da Dante " << endl; ar.stampaTit("Dante"); cout << "Numero di libri di genere Romanzo scritti dagli autori la cui iniziale e' tra A e D" << endl; cout << ar.conta("Romanzo",'A','D') << endl << endl; ar.rimuovi(3); ar.rimuovi(1); cout << "Stampa dell'archivio " << endl; ar.stampa(); }