Linguaggio macchina Z80 (note)


Sommario
REGISTRI CPU Z80:


Generali e indice
A
BC
DE
HL

IX
IY


Accumulatore a 8 bit 
16 bit scomponibile in B e C a 8 bit
16 bit scomponibile in D e a 8 bit
16 bit scomponibile in H e L  a 8 bit  

Registro indice a 16 bit 
Registro indice a 16 bit

Controllo ambiente e gestiti dall'hardware
SP
I
F
R
PC
IFF1/IFF2
IMFa/IMFb

Stack pointer a 16 bit
Controllo interruzioni IM2 8 bit

Flags 8 bit
Rinfresco RAM dinamiche 8 bit
Program counter 16 bit
2 bit INT enable
2 bit interrupt mode


I registri A F BC DE HL sono duplicati in un set di registri alternativo commutabile con le istruzioni EX AF,AF' e EXX.

Il registro B viene anche usato come contatore a 8 bit nell'istruzione DJNZ.

Il registro HL viene anche usato come accumulatore nelle operazioni a 16 bit.

I registri HL DE BC vengono usati insieme nelle istruzioni sui blocchi di dati.



AVVERTENZE:

Nel codice assembly un valore costante può essere scritto in decimale, binario o esadecimale, e può rappresentare a seconda dell'istruzione un indirizzo di memoria, un bit, un offset o un valore immediato da assegnare ad un registro o con cui effettuare un'operazione logica/aritmetica.

Le label possono indicare dei valori costanti (specificati con .equ), o degli indirizzi di memoria di istruzioni (o blocchi di dati), quando sono scritte in corrispondenza di essi.

Generalmente la sintassi HL indica il valore a 16 bit del registro HL, mentre la sintassi (HL) indica il byte contenuto all'indirizzo di memoria specificato dal valore di HL.

Generalmente Ia sintassi (12000) indica il byte contenuto all'indirizzo di memoria 12000, mentre la sintassi (label) indica il byte contenuto all'indirizzo di memoria specificato dal valore della label.

In memoria i dati a 16 bit vengono sempre scritti prima byte basso e poi byte alto, quindi LD (12000),HL scrive in (12000) il valore di L e in (12001) il valore di H.



SALTI:

JR label e JP label sono i salti incondizionati: relativo corto il primo (da -128 a +127 byte rispetto all'indirizzo di inizio dell'istruzione successiva) e assoluto il secondo (da 0 a 65535). Scrivendo delle label come punti di arrivo dei salti, l'assemblatore calcola automaticamente i valori numerici dei salti.

I salti possono essere condizionati dallo stato dei flags:
 
JR C JP C
Salta se riporto/prestito
JR NC
JP NC
Salta se non riporto/prestito
JR Z
JP Z
Salta se zero
JR NZ
JP NZ
Salta se non zero
JR M JP M
Salta se negativo
JR P
JP P Salta se positivo




CONFRONTI:

L'istruzione CP effettua un confronto a 8 bit (sottrazione) tra A e l'operando specificato, ad esempio CP A,12 effettua la sottrazione A-12 (senza alterare il valore di A).

L'operazione imposta i flags in accordo con il risultato: il bit Z viene settato se il risultato della sottrazione è zero, il bit C (flag carry CF da non confondere con il registro C) viene settato se si è avuto un prestito, il bit di segno viene impostato in base al valore del bit 7 del risultato (negativo se bit 7=1).

Controllando lo stato dei flags dopo un'operazione di confronto (o una qualsiasi sottrazione) si può quindi stabilire la relazione  tra i due valori: 

C A < operando,  operando > A
NC
A >= operando, operando <= A
Z
A == operando
NZ
A != operando
C o Z
A <= operando, operando >= A
NC e NZ
A > operando, operando < A
M Risultato negativo
P
Risultato positivo


Per i soli test > e <=, è possibile scambiare gli operandi durante il confronto e ridurre ad uno solo il flag da controllare:

LD B,A     ;salva A in B
LD A,12
CP A,B ;calcola 12 - vecchio_A
LD A,B ;recupera vecchio_A
 
C A > operando, operando < A
NC
A <= operando, operando >= A


Con SBC HL,registro_16_bit è possibile confrontare il valore a 16 bit di HL con quello di un altro registro generale a 16 bit (DE BC), però bisogna prima azzerare il flag C di riporto/prestito, ed eventualmente salvarsi da qualche parte il vecchio valore di HL perchè questa sottrazione ne altera il valore (in HL viene messo il risultato della sottrazione):

AND  A      ;azzera flag CF
PUSH HL ;salva HL nello stack
SBC HL,DE ;HL = HL - DE - CF
POP HL ;recupera vecchio valore di HL



CICLI:

DJNZ label decrementa B e salta a label se B<>0.

Il valore di B può andare da 0 a 255, se vale 0 DJNZ effettua 256 cicli.

DJNZ effettua un salto relativo corto come  JR da -128  a +127 byte rispetto all'indirizzo di inizio dell'istruzione successiva.



SUBROUTINES:

CALL label salva nello stack l'indirizzo della prossima istruzione e salta  all'indirizzo assoluto specificato da label (da 0 a 65535).

RET ritorna da una subroutine recuperando l'indirizzo di ritorno dallo stack.

Chiamate e ritorni da subroutines possono essere condizionate dallo stato dei flags esattamente come i salti (ad esempio CALL C o RET NZ).

 


ISTRUZIONI SU BLOCCHI DI DATI:

Queste istruzioni servono per spostare o effettuare ricerche in blocchi di byte, coinvolgono i registri HL e DE come indici sorgente/destinazione a 16 bit, e BC come contatore a 16 bit. 

LDI   ;(HL)->(DE)  HL+1  DE+1  BC-1
LDD
;(HL)->(DE)  HL-1 DE-1 BC-1
LDIR ;(HL)->(DE)  HL+1 DE+1 BC-1 ripeti se BC<>0
LDDR
;(HL)->(DE)  HL-1 DE-1 BC-1 ripeti se BC<>0

CPI ;A-(HL) HL+1 BC-1
CPD
;A-(HL) HL-1 BC-1
CPIR ;A-(HL) HL+1 BC-1 ripeti se BC<>0 e Z=0
CPDR
;A-(HL)  HL-1 BC-1 ripeti se BC<>0 e Z=0

CPI e CPD confrontano A con il valore in (HL) impostando i flag come con una operazione CP, poi incrementano (o decrementano) HL e decrementano BC

CPIR e CPDR confrontano A con (HL) al massimo per BC volte, la ricerca si arresta quando BC=0 o quando il flag Z=1 (trovato valore corrispondente e HL punta all'elemento successivo).



STACK:

All'accensione il valore di SP viene impostato a zero. Considerando che lo stack si estende verso indirizzi più bassi, e che SP viene prima decrementato e poi usato per indirizzare la memoria, il primo dato a 16 bit salvato nello stack verrebbe scritto agli indirizzi 65534:65535. Se questi indirizzi non sono adatti al sistema in uso, prima di usare lo stack il valore di SP va regolato in modo da puntare ad un'area di memoria valida.

E' possibile allocare dello spazio sullo stack spostandolo verso indirizzi più bassi, e successivamente liberare lo spazio :

LD   IX,-16    ;16 byte da allocare
ADD IX,SP
;IX punta all'inizio dello spazio
LD SP,IX ;sposta lo stack in basso
......
LD HL,16 ;16 byte da deallocare
ADD HL,SP
LD SP,HL ;sposta lo stack in alto



REGISTRI ALTERNATIVI:

I registri alternativi permettono di evitare o ridurre l'uso della memoria per salvare temporaneamente i valori dei registri generali. La commutazione tra i due banchi è una delle operazioni più veloci.

EX   AF,AF'  ;scambia A F con A' F'
EXX ;scambia B C D E H L
;con B' C' D' E' H' L'


Esempio, salva i registri generali in risposta ad un'interrupt, risparmia 4 scritture e 4 letture dello stack, e impiega 16 cicli di clock anziché 84:

EX   AF,AF'
EXX
... gestione interrupt...
EXX
EX AF,AF'
EI
RETI

Esempio, appoggiandosi allo stack è possibile passare valori tra i registri di un set e quelli dell'altro:
PUSH DE
PUSH HL
EXX
POP HL
POP DE

Esempio, lavorare con i registri alternativi ma ritornare il valore di A:
EXX AF,AF'
EXX
......
LD B,A
EXX AF,AF'
LD A,B
EXX


 

Pagina realizzata da Claudio Fin
Ultimo aggiornamento 5-5-2013