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).
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.
Sito realizzato in base al
template offerto da
http://www.graphixmania.it