Esame di Calcolatori Elettronici Appello del 25/9/'02 (Telecomunicazioni) Esercizio 1) Realizzare in Assembler GNU la seguente funzione (scrivere sul file es1.s ed eseguire): struct ss {int v1[5]; char c; int v2[5];}; extern "C" ss f(ss ss1, ss& ss2) { ss ss3; int i; for (i=0; i<5; i++) { ss2.v1[i]=ss1.v1[i]+ss1.c; ss3.v1[i]=ss1.v2[i]*ss1.v2[i]; } for (i=0; i<5;i++) { ss2.v2[i]=ss1.v2[i]+ss1.v2[4]; ss3.v2[i]=ss1.v1[i]*ss1.v1[i] + ss1.v1[1]; } ss2.c=ss3.c=(char)ss2.v1[1]; 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: struct punto{ double x,y;}; class poligono { int nvertici; punto* pp; double lung(const punto&, const punto&) const; public: poligono(){nvertici=0; pp=0;} poligono(int n, const punto v[]); poligono& operator=(const poligono& pol); double perimetro() const; poligono::~poligono() {delete[] pp;} poligono operator-(const poligono& pol) const; void stampapol() const; }; La classe poligono realizza un poligono utilizzando un vettore (individuato dal membro pp) per la memorizzazione dei vertici. Il membro nvertici contiene il numero dei vertici del poligono. Realizzare: 1) l'operatore operator=(), che assegna al poligono su cui è applicato l'operatore il poligono passato come parametro all'operatore stesso; l'operatore restituisce il poligono su cui è applicato l'operatore; 2) la funzione membro perimetro(), che restituisce il perimetro del poligono; nel realizzare questa funzione si consiglia di utilizzare una funzione privata lung() (da definire) che restituisce la lunghezza di un lato del poligono (si ricorda che la radice quadrata è realizzata dalla funzione sqrt() dichiarata nel file math.h); 3) l'operatore operator-() che restituisce un poligono composto solo dai vertici che appartengono al poligono a cui si applica l'operatore e non appartengono al poligono passato come parametro. Il costruttore poligono(int n, const punto v[]) costruisce un poligono di n vertici e inizializza ogni vertice con i punti contenuti nel vettore v; la funzione membro stampapol() stampa su uscita standard i vertici contenuti nel poligono. Il costruttore poligono(int n,const punto v[]) e la funzione stampapol() sono implementati 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 inizializzando il campo v1 con gli interi da 0 a 4, il campo c con il carattere 'a', ed il campo v2 con gli interi da 0 a 4; 2. dichiara due strutture ss2 e ss3 di tipo ss; 3. chiama la funzione f() passandole ss1 e ss2 come primo e secondo argomento, rispettivamente, ed assegnando la struttura restituita a ss3; 4. stampa su uscita standard le strutture ss2 e ss3; 5. dichiara un vettore pp di 5 strutture di tipo punto; 6. inizializza i campi x e y di ogni punto contenuto nel vettore pp con gli interi contenuti, rispettivamente, nei vettori v1 e v2 della struttura ss3; 7. dichiara un poligono pol1 passando l'intero 5 e pp al costruttore; 8. stampa su uscita standard il poligono pol1; 9. stampa su uscita standard il perimetro del poligono pol1; 10. dichiara un poligono pol2 passando al costruttore l'intero 3 e pp; 10. dichiara un poligono pol3; 11. assegna pol1 a pol3; 12. stampa su uscita standard pol3; 13. sottrae pol2 a pol3 ed assegna il risultato a pol3; 14. stampa su uscita standard pol3. Esame di Calcolatori Elettronici Appello del 25/9/'02 (Telecomunicazioni) Soluzioni Esercizio 1 .text .globl _f _f: pushl %ebp movl %esp,%ebp subl $48,%esp pushl %edi pushl %esi pushl %ebx pushl %edx movl 56(%ebp),%ebx movl $0,-48(%ebp) for1: cmpl $5,-48(%ebp) jl corpo1 jmp fine1 corpo1: movl -48(%ebp),%ecx movsbl 32(%ebp),%esi #(int)ss1.c addl 12(%ebp,%ecx,4),%esi #ss2.v1[i]=ss1.v1[i]+ss1.c movl %esi,(%ebx,%ecx,4) movl 36(%ebp,%ecx,4),%eax #ss1.v2[i]*ss1.v2[i] imull 36(%ebp,%ecx,4) movl %eax, -44(%ebp,%ecx,4) incl -48(%ebp) jmp for1 fine1: movl $0,-48(%ebp) for2: cmpl $5,-48(%ebp) jl corpo2 jmp fine2 corpo2: movl -48(%ebp),%ecx movl 52(%ebp),%esi #ss2.v2[i]=ss1.v2[i]+ss1.v2[4] addl 36(%ebp,%ecx,4),%esi movl %esi, 24(%ebx,%ecx,4) movl 12(%ebp,%ecx,4),%eax #ss3.v2[i]=ss1.v1[i]*ss1.v1[i] + ss1.v1[1] imull 12(%ebp,%ecx,4) addl 16(%ebp), %eax movl %eax, -20(%ebp,%ecx,4) incl -48(%ebp) jmp for2 fine2: movb 4(%ebx),%al #ss2.c=ss3.c=(char)ss2.v1[1] movb %al,-24(%ebp) movb %al,20(%ebx) movl 8(%ebp),%eax #return ss3 leal -44(%ebp),%esi movl %eax,%edi cld movl $11,%ecx rep movsl popl %edx popl %ebx popl %esi popl %edi leave ret Esercizio 2 //file cc.h esistente struct punto{ double x,y;}; class poligono { int nvertici; punto* pp; double lung(const punto&, const punto&) const; public: poligono(){nvertici=0; pp=0;} poligono(int n, const punto v[]); poligono(const poligono& pol); poligono& operator=(const poligono& pol); double perimetro() const; poligono::~poligono() {delete[] pp;} poligono operator-(const poligono& pol) const; void stampapol() const; }; //file ccob.cc esistente #include "cc.h" #include poligono::poligono(int n, const punto v[]) { nvertici=n; pp=new punto[nvertici]; for (int i=0; i poligono& poligono::operator=(const poligono& pol) { if (this!=&pol) { nvertici=pol.nvertici; if (pp) delete[] pp; pp=new punto[nvertici]; for (int i=0; i struct ss {int v1[5]; char c; int v2[5];}; extern "C" ss f(ss ss1, ss& ss2); void stampa(const ss& s) { cout << "v1[] = "; for (int i=0; i<5; i++) cout << s.v1[i] << ' '; cout << endl; cout << "c = " << s.c << endl; cout << "v2[] = "; for (int i=0; i<5; i++) cout << s.v2[i] << ' '; cout << endl << endl; } void main() { ss ss1={{0,1,2,3,4},'a',{0,1,2,3,4}}, ss2, ss3; ss3=f(ss1,ss2); cout << "Stampa della struttura ss2 " << endl; stampa(ss2); cout << "Stampa della struttura ss3 " << endl; stampa(ss3); punto pp[5]; for (int i=0; i<5; i++) { pp[i].x=ss3.v1[i]; pp[i].y=ss3.v2[i]; } poligono pol1(5,pp); cout << "Stampa del poligono pol1 " << endl; pol1.stampapol(); cout << "Perimetro di pol1 = " << pol1.perimetro() << endl<< endl; poligono pol2(3,pp), pol3; pol3=pol1; cout << "Stampa del poligono pol3 " << endl; pol3.stampapol(); pol3=pol3-pol2; cout << "Stampa del poligono pol3 " << endl; pol3.stampapol(); }