Vediamo un programma esemplificativo che serve per testare l'area di memoria di 8000h locazioni comprese fra gli indirizzi 8000h e FFFFh per individuare eventuali parole di memoria non correttamente funzionanti.
La tecnica consiste nello scrivere in ogni parola di memoria il valore 00h (8 bit a zero) e poi rileggerlo e quindi scrivere il valore FFh esadecimale (8 bit a uno) e poi rileggerlo. Se i valori scritti e quelli successivamente letti sono uguali, vuol dire che la parola di memoria funziona correttamente, altrimenti significa che c'è un errore.
LD HL,0FFFFh ; inizializza HL con FFFFh (fine area di memoria) LD D, 0 ; azzera il contatore degli errori inizio: LD (HL),0 ; azzera la locazione puntata da HL LD A, (HL) ; legge la locazione puntata da HL CP 0 ; confronta il valore letto con zero JP NZ,errore ; se sono diversi salta a errore LD (HL),0FFh ; carica F nella locazione puntata da HL LD A, (HL) ; legge la locazione puntata da HL CP 0FFh ; confronta il valore letto con FF JP NZ,errore ; se sono diversi salta a errore decr: DEC HL ; decrementa HL ; Le istruzioni seguenti servono per testare se HL vale 7FFFh LD A,H ; copia H in A CP 7Fh ; testa se A vale 7Fh JP NZ, inizio ; se è diverso ricomincia da inizio fine: LD A,D ; carica 0 in A OUT (0),A ; visualizza il numero di errori (se 0, allora tutto ok) HALT errore: INC D ; incrementa il contatore degli errori JP decr ; torna a decr
Si osservi in particolare che:
Una possibile traduzione in linguaggio C del ciclo precedente è questa:
i=FINE;
err=0;
while (i!=INIZIO)
{
mem [i]=0;
if (mem [i]!=0)
err++;
mem [i]=0xFF;
if (meme[i]!=0xFF) err++;
i--;
}
Vediamo adesso un esempio di programma per acquisire 10 valori da IB, salvarli in memoria e quindi visualizzarli su OA in ordine inverso (dall'ultimo al primo). Il programma utilizza alcuni cicli di attesa su un pulsante collegato con IA per consentire all'utente di temporizzare l'acquisizione e la visualizzazione dei valori:
LD HL, 8000h ;inizializza HL all'inizio della RAM LD B,10 ; inizializza contatore numero valori attesa1: IN A,(1) ; doppio ciclo di attesa (pressione e rilascio pulsante su IB) CP 0 JP Z,attesa1 attesa2: IN A,(1) CP 0 JP NZ,attesa2 ciclo1: IN A,(0) ; acquisisce un valore da IA LD (HL),A ; lo carica in memoria INC HL ; incrementa il puntatore in memoria DEC B ; decrementa il contatore del numero valori JP Z,stampa JP attesa1 stampa: LD B,10 ; inizializza contatore numero valori ciclo2: DEC HL ; decrementa puntatore in memoria LD A,(HL) ; carica il valore dalla memoria OUT (0),A ; visualizza il valore su OA DEC B ; decrementa il contatore del numero valori JP Z,fine attesa3: IN A,(1) ; doppio ciclo di attesa prima di proseguire CP 0 JP Z,attesa3 attesa4: IN A,(1) CP 0 JP NZ,attesa4 JP ciclo2 fine: HALT
Consideriamo un programma in grado di contare il numero dei bit a 1 all'interno di un dato numero. Per esempio, se A = 1001101 il programma fornisce in uscita il valore 4 (ci sono 4 bit a 1 nel numero dato):
IN A,(0) ; cin>>A
LD B,8 ; B = 8
LD C,0 ; C = 0
ciclo:
DEC B ; B--
JP M,fine ; if (B<0) goto fine
BIT 0,A ; if (!isBitSet(A,0) // testa il bit 0 di A
JP Z,shift ; goto shift
INC C ; C++
shift:
SRL A ; A >>
1 // shifta A a destra di 1 bit
JP ciclo ; goto ciclo
fine:
LD A,C ; A = C
OUT (0),A ; cout << A
HALT
Il programma funziona shiftando A ripetutamente verso destra e ogni volta testando il bit 0 meno significativo di A (quello più a destra). Se questo bit vale 1, viene incrementato il contatore C.
Poiché questo particolare programma si limita a shiftare A verso destra senza fare alcun uso dei bit "persi" né del contenuto del registro dei flag, avremmo potuto usare al posto di SRL A l'istruzione RRCA o anche l'istruzione SRA A, senza nessuna differenza nel funzionamento.
Sito realizzato in base al
template offerto da
http://www.graphixmania.it