ELEMANIA
Z80 - Programmi di esempio
Radice quadrata intera con subroutine

Il seguente programma calcola la radice quadrata intera di un numero. La radice quadrata intera è il numero intero più grande il cui quadrato è minore o uguale di un numero dato. Per esempio, la radice quadrata intera di 6 è 2, poiché il quadrato di 2 fa 4, mentre il quadrato di 3 fa 9 (e dunque supera il numero dato 6).

       IN A,(0) ; numero di cui si vuole calcolare la radice quadrata intera
       LD B,A ; copio il numero in B
       LD C,0 ; inizializzo a 1 il contatore

ripeto:
       INC C
       LD A,C       
       CALL quadrato
       CP B       
       JP M,ripeto ; se il quadrato è minore del numero dato

       JP Z, fine ; se il quadrato è perfetto salto a fine
       DEC C ; C--
fine:
       LD A,C
       OUT (0),A
       HALT

quadrato:
       PUSH BC ; salva il registri B e C sullo stack
calcolo:
       LD B,A ; copia A in B
       LD C,A ; e in C
       LD A,0 ; azzera A
ciclo:
       ADD A,C ; A = A + C
       DEC B ; B --
       JP NZ,ciclo ; ripete finché B non si azzera

       POP BC ; ripristina B e C dallo stack
       RET

Il programma usa la subroutine quadrato per fare il calcolo dei quadrato di C e trovare, per tentativi, la radice intera. Si noti come sia fondamentale salvare i registri B e C sullo stack all'inizio della subroutine, dal momento che quest'ultima modifica il contenuto di tali registri (che sono usati anche dal programma principale).

Calcolo numeri primi

Vediamo infine un esempio riassuntivo un po' meno banale dei precedenti.

Il seguente programma calcola tutti i numeri primi compresi fra 2 e 255 e il visualizza sull'uscita di indirizzo 0:

            LD SP,0 ; azzera lo SP
            LD C,1 ; inizializza C col primo numero da testare meno 1

test:
            INC C ; incrementa il numero da testare
            JP Z, fine ; se zero, fine numeri (255+1 -> 0)

            CALL verifica ; chiama la funzione per il test di primalità

            CP 0 ; se la funzione torna 0
            JP Z, test ; il numero non è primo, si prova con un altro

            LD A,C ; il numero è primo
            OUT (0),A ; visualizza il numero
            JP test ; prosegue
fine:
            HALT    ; termine del programma

            ; **** SUBROUTINE VERIFICA DELLA PRIMALITA' DI UN NUMERO
verifica:
            push BC            ; salva sullo stack tutti i registri
            push DE
            push HL

            LD B,2 ; inizializza a 2 il divisore
ciclo:
            LD A,C ; ripristina il numero da testare
            CP B ; se B==A
            JP Z, primo ; il numero è primo

            CALL resto ; calcola il resto della divisione A/B

            CP 0 ; se il resto è zero
            JP Z, noprimo ; il numero non è primo
            INC B ; incrementa B
            JP ciclo ; ripeto il ciclo di verifica
primo:
            LD A,1
noprimo:
            POP HL            ; ripristina i registri dallo stack
            POP DE
            POP BC
            RET

            ; **** SUBROUTINE CHE CALCOLA IL RESTO DELLA DIVISIONE A/B

resto:
            SUB B           ; sottraggo B da A
            JP P, resto     ; finché non viene un risultato negativo
            ADD A,B         ; correggo aggiungendo B
            RET

Nell'esempio sono presenti due subroutine:

All'inizio della subroutine verifica si può osservare un tipico esempio di salvataggio di tutti i registri (tranne quelli coinvolti nel passaggio di valori fra chiamante e subroutine) sullo stack. Alla fine della subroutine il contenuto dei registri salvati viene ripristinato. Questo garantisce che eventuali modifiche nel contenuto dei registri fatte dalla funzione non si ripercuotano sul programma principale.

 

precedente - successiva

Sito realizzato in base al template offerto da

http://www.graphixmania.it