Esame di Calcolatori Elettronici Appello del 10/1/'02 (Telecomunicazioni) Esercizio 1) Realizzare in Assembler GNU la seguente funzione (scrivere sul file es1.s ed eseguire): struct ss { int v; char a[4]; int b[4]; }; extern "C" ss f(ss& ss1, ss ss2) { ss ss3; int i; ss1.v = ss2.v+ss2.b[1]; ss3.v = ss2.v+ss2.b[3]; for (i = 0; i < 4; i++) { ss1.a[i] = ss2.a[i]; ss3.a[i] = ss1.a[i]++;} for (i = 0; i < 4; i++) { ss1.b[i] = ss2.b[i]+3; ss3.b[i] = ss2.b[i]+ss1.b[i]; } 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: enum booleano {F,T}; class lista { struct elem {char* nome; int num; elem* next;}; elem* testa; public: lista() {testa=0;} ~lista(); void stampa(); void ins(const char [], int); void build(const char [], const char [], int); int conta(char, int); booleano canc(const char [], int); }; La classe lista realizza una lista ordinata per valori alfabeticamente decrescenti del campo nome. Realizzare: 1) la funzione membro build(), che, apre in lettura il file il cui nome e' passato come primo parametro e ripete fino a raggiungere la fine del file le azioni seguenti: legge dal file una stringa (di al massimo 10 caratteri) ed un numero intero e, se la stringa e' uguale alla stringa passata come secondo parametro ed il numero intero e' minore del numero intero passato come terzo parametro, li inserisce nella lista; 2) la funzione membro conta() che conta il numero di elementi il cui campo nome inizia con il carattere passato come primo parametro ed il cui campo num e' minore del numero intero passato come secondo parametro; 3) la funzione membro canc() che cancella dalla lista tutti gli elementi il cui campo nome coincide con la stringa passata come primo parametro ed il cui campo num e' minore del numero intero passato come secondo parametro; la funzione restituisce F se non viene cancellato nessun elemento; altrimenti restituisce T. Il distruttore ~lista() elimina tutti gli elementi della lista. La funzione membro stampa() stampa su uscita standard tutti gli elementi della lista. La funzione membro ins() inserisce una stringa ed un numero intero nella lista mantenendo la lista ordinata. Le funzioni ~lista(), stampa() e ins() sono implementate 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 campo v a 10, il campo a con i caratteri da 'b' a 'e' e il campo b con gli interi da 1 a 4; 3. dichiara una struttura ss3 di tipo ss; 4. chiama la funzione f() passando ss1 e ss2 come, rispettivamente, primo e secondo parametro e assegna il risultato ad ss3; 5. stampa su uscita standard le strutture ss1 e ss3; 6. dichiara una lista l; 7. chiama la funzione build() passandole "ingr", "minni" e ss1.b[0]; 8. chiama la funzione build() passandole "ingr", "pippo" e ss1.b[1]; 9. chiama la funzione build() passandole "ingr", "pluto" e ss1.b[2]; 10. stampa la lista su uscita standard; 11. stampa su uscita standard il numero di elementi il cui campo nome inizia per il carattere 'p' ed il cui campo num e' minore di ss1.b[3]; 12. cancella gli elementi il cui campo nome coincide con la stringa "pippo" ed il cui campo num e' minore di ss1.b[0]; se non esiste nessun elemento stampa il messaggio "Nessun elemento trovato"; 13. stampa la lista su uscita standard. Esame di Calcolatori Elettronici Appello del 10/1/2002 - Soluzioni # file es1.s .text .global _f _f: pushl %ebp movl %esp,%ebp subl $28,%esp pushl %edi pushl %esi pushl %edx pushl %ecx movl 12(%ebp),%edx #indir. ss1 in edx movl 16(%ebp),%edi #ss1.v= ss2.v+ss2.b[1] addl 28(%ebp),%edi movl %edi,(%edx) movl 16(%ebp),%edi #ss3.v= ss2.v + ss2.b[3] addl 36(%ebp),%edi movl %edi,-24(%ebp) movl $0,-28(%ebp) #inizializ. i for1: cmpl $4,-28(%ebp) jl corpo1 jmp finefor1 corpo1: movl -28(%ebp),%ecx #ss1.a[i]= ss2.a[i] movb 20(%ebp,%ecx), %al movb %al, 4(%edx,%ecx) movb %al,-20(%ebp,%ecx) #ss3.a[i]=ss1.a[i]++ incb %al movb %al, 4(%edx,%ecx) incl -28(%ebp) jmp for1 finefor1: movl $0,-28(%ebp) #inizializ. i for2: cmpl $4,-28(%ebp) jl corpo2 jmp finefor2 corpo2: movl -28(%ebp),%ecx #ss1.b[i]=ss2.b[i]+3 movl 24(%ebp,%ecx,4),%eax addl $3,%eax movl %eax,8(%edx,%ecx,4) movl 24(%ebp,%ecx,4),%eax #ss3.b[i]=ss2.b[i]+ss1.b[i] addl 8(%edx,%ecx,4),%eax movl %eax,-16(%ebp,%ecx,4) incl -28(%ebp) jmp for2 finefor2:movl 8(%ebp),%eax leal -24(%ebp),%esi movl %eax,%edi cld movl $6,%ecx rep movsl popl %ecx popl %edx popl %esi popl %edi leave ret Esercizio 2 //file cc.h esistente enum booleano {F,T}; class lista { struct elem {char* nome; int num; elem* next;}; elem* testa; public: lista() {testa=0;} ~lista(); void stampa(); void ins(const char [], int); void build(const char [], const char nome[], int n); int conta(char in, int num); booleano canc(const char nome[], int num); }; //file ccob.cc esistente #include #include #include "cc.h" void lista::ins(const char nome[], int num) { elem* q,* p; for (p=q=testa; p!=0 && strcmp(nome, p->nome) <0; p=p->next) q=p; elem* r=new elem; r->nome=new char[strlen(nome)+1]; r->num=num; strcpy(r->nome, nome); r->next=p; if (p==testa) testa=r; else q->next=r; } lista::~lista() { elem* q; for (elem* p=q=testa; q!=0; p=q) { q=p->next; delete[] p->nome; delete p;} } void lista::stampa() { for (elem* p=testa; p!=0; p=p->next) cout << p->nome << '\t' << p->num << endl; } //file es2.cc #include #include #include "cc.h" void lista::build(const char nomefile[], const char nome[], int n) { ifstream in(nomefile); if (!in) { cerr << "Errore nell'apertura del file " << nomefile << endl; exit(1); } char input[10]; int num; while (in >> input >> num) if (!strcmp(input,nome) && num < n) ins(input,num); } int lista::conta(char in, int num) { int cont=0; elem* p; for (p=testa; p!=0 && p->nome[0]>in;p=p->next); for (;p!=0 && p->nome[0]==in; p=p->next) if (p->num < num) cont++; return cont; } booleano lista::canc(const char nome[], int num) { elem* q,* p; booleano trovato=F; for (p=q=testa; p!=0 && strcmp(nome, p->nome) <0; p=p->next) q=p; for (;p!=0 && !strcmp(nome,p->nome); ) if (p->num < num) { if (p==testa) { testa=q=p->next; delete[] p->nome; delete p; p=q; } else { q->next=p->next; delete[] p->nome; delete p; p=q->next; } trovato=T; } else { q=p; p=p->next; } return trovato; } Esercizio 3 /file es3.cc #include #include #include "cc.h" struct ss { int v; char a[4]; int b[4]; }; extern "C" ss f(ss& ss1, ss ss2); void stampa(ss s) { cout << "v= " << s.v << endl; cout << "a= "; for (int i=0; i<4; i++) cout << s.a[i] << ' '; cout << endl; cout << "b= "; for (int i=0; i<4; i++) cout << s.b[i] << ' '; cout << endl << endl; } void main() { ss ss1,ss2={10, {'b','c','d','e'},{1,2,3,4}}, ss3; ss3=f(ss1,ss2); cout << "Stampa della struttura ss1 " << endl; stampa(ss1); cout << "Stampa della struttura ss3 " << endl; stampa(ss3); lista l; l.build("ingr","minni",ss1.b[0]); l.build("ingr","pippo",ss1.b[1]); l.build("ingr","pluto",ss1.b[2]); l.stampa(); cout << "Numero di elementi " << l.conta('p',ss1.b[3]) << endl; if (!l.canc("pippo",ss1.b[0])) cout << "Nessun elemento trovato " << endl; l.stampa(); }