* Esercizio 13 * * Realizzare un programma che, facendo uso della subroutine STRLEN capace di restituire la lunghezza * di una stringa di caratteri, valuti la piu' lunga tra due stringhe date. * Le stringhe si intendano null-terminated. * Ipotesi: * L'area dati del programma principale (e accessibile solo da esso) contenga: * - le due stringhe null-terminated di indirizzo rispettivamente pari a STR1 e STR2; * - una locazione di indirizzo RES destinata a contenere il risultato. * Il risultato sia: * - pari a 1 se STR1 e' piu' lunga di STR2; * - pari a 2 se STR2 e' piu' lunga di STR1; * - 0 altrimenti. * La subroutine accetti come parametro di ingresso l'indirizzo di inizio della stringa e restituisca la sua lunghezza complessiva. * I parametri vengano passati attraverso lo stack. * Area Istruzioni ORG $8000 START MOVE.L #$0011DDDD,D0 * "Sporca" i registri D0 e A0 e A6 per mostrare MOVE.L #$AAAAAAAA,A0 * che verranno correttamente ripristinati all'uscita MOVE.L #$FFFFFFFF,A6 * dalle subroutines. SUB.L #2,SP * Alloca una word per il risultato della sub su STR1 MOVE.L #STR1,-(SP) * Push sullo stack dell'indirizzo di STR1 JSR STRLEN * Salta a STRLEN MOVE.W 4(SP),D0 * Copia il risultato in D0 MOVE.L #STR2,(SP) * Sovrascrive sullo stack l'indirizzo di STR2: l'area stack per il passaggio dei parametri e' infatti ancora allocata JSR STRLEN * Salta a STRLEN SUB.W 4(SP),D0 * Sottrae il risultato a D0. (Prestare attenzione al fatto che si sta operando su due Word) BEQ FINE * Se si e' ottenuto zero, puo' saltare direttamente a fine poiche' RES e' stato inizializzato a zero... BPL MAGGIORE * ...altrimenti salta a MAGGIORE... MINORE MOVE.B #2,RES * ...altrimenti non puo' che essere minore. BRA FINE MAGGIORE MOVE.B #1,RES FINE ADDA.L #6,SP * Dealloca l'area di stack STOP #$2000 * Area Dati ORG $8400 STR1 DC.B 'Prima',0 * Prima stringa STR2 DC.B 'Seconda',0 * Seconda stringa RES DC.B 0 * Area di memoria per il risultato * Subroutine STRLEN ORG $8800 OFF_ADDR EQU 8 * Offset rispetto al frame-pointer dell'indirizzo della stringa OFF_LEN EQU 12 * Offset rispetto al frame-pointer del parametro di uscita STRLEN LINK A6,#0 * Imposta il frame-pointer su A6 MOVE.L D0,-(SP) * Push sullo stack di D0 destinato ad accumulare il numero di caratteri della stringa MOVE.L A0,-(SP) * Push sullo stack di A0 destinato a contenere l'indirizzo dell'elemento correntemente esaminato CLR.L D0 * Pulisce il registro accumulatore D0 MOVEA.L OFF_ADDR(A6),A0 * Copia l'indirizzo della stringa da esaminare in A0 LOOP CMP.B #0,(A0)+ * Compara con zero l'elemento correntemente puntato e sposta il puntatore all'elemento successivo BEQ FINESUB * Se e' zero la stringa e' terminata e salta a FINESUB... ADDQ.W #1,D0 * ...altrimenti incrementa D0... BRA LOOP * ...e ritorna ad analizzare l'elemento successivo. FINESUB MOVE.W D0,OFF_LEN(A6) * Sposta la lunghezza della stringa nello stack MOVE.L (SP)+,A0 * Ripristina il registro A0 MOVE.L (SP)+,D0 * Ripristina il registro D0 UNLK A6 * Ripristina il vecchio frame-pointer RTS * Ritorna il controllo al chiamante END START