ELEMANIA
Z80 - Istruzioni aritmetiche
Somma a 8 bit

Nell'istruzione somma (ADD)  a 8 bit l'accumulatore A è sempre usato come primo operando e
come destinazione del risultato, mentre il secondo operando può essere:

a) un valore immediato a 8 bit;
b) il contenuto di un registro a 8 bit;
c) il contenuto di una locazione di memoria, specificata con indirizzamento indiretto tramite
HL, o i registri indice IX o IY.

Vediamo alcuni esempi:

        ADD A,01h          ; valore immediato (qui pari a 01h): A = A + 01h
        ADD A,B             ; registro (A, B, C, D, E, H o L): A = A + B
        ADD A,(HL)         ; locazione di memoria puntata da HL: A = A + (HL)
        ADD A,(IX+66)    ; loc.puntata da IX +16 (per esempio): A = A + (IX+16)
        ADD A,(IY+15)    ; loc.puntata da IY +16 (per esempio): A = A + (IY+16)

Al termine della ADD, se la somma ha generato un riporto, viene posto a 1 il flag carry del registro dei flag. 

Una variante importante dell'istruzione di somma è la ADC (somma con riporto):

        ADC A,01h         ; valore immediato (qui pari a 01h): A = A + 01h + carry
        ADC A,B            ; registro (A, B, C, D, E, H o L): A = A + B + carry
        ADC A,(HL)        ; locazione di memoria puntata da HL: A = A + (HL) + carry
        ADC A,(IX+10)   ; loc. puntata da IX +n: A = A + (IX+n) + carry
        ADC A,(IY+36)   ; loc. puntata da IY +n: A = A + (IY+n) + carry

Questa istruzione è come la precedente, solo che in questo caso la ADC tiene conto, nel fare il
calcolo, anche del riporto eventualmente già presente nel flag di carry del registro dei flag. In altre parole, somma al registro accumulatore A la sorgente s, più 1 se nel flag di carry abbiamo memorizzato un riporto e rimette il risultato in A.

Somma a 16 bit

L'aritmetica a 16 bit dello Z80 è piuttosto limitata e comprende solo alcune operazioni. Nel caso della somma a 16 bit,  il primo operando e la destinazione dell'operazione sono il registro accoppiato HL oppure i registri indice IX o IY. Il secondo operando può essere soltanto un registro interno a 16 bit. Le combinazioni possibili sono le seguenti:

        ADD HL,BC   ; somma HL con BC (BC, DE. HL): HL = HL + BC
        ADC HL,BC   ; come prima, ma cin il riporto: HL = HL + BC + carry
        ADD HL,SP   ; somma HL con lo stack pointer SP: HL = HL + SP
        ADC HL,SP   ; come la precedente con riporto: HL = HL + SP + carry
        ADD IX,BC   ; somma IX con BC (oppure DE): IX = IX + BC
        ADD IY,BC   ; come la precedente con IY: IY = IY + BC
        ADD IX,SP   ; somma IY (oppure IX) con SP: IY = IY + SP

Si noti che non si tratta di vere operazioni a 16 bit, perché l'ALU è da 8 bit: l'operazione è scomposta internamente in due fasi successive, prima sul byte "basso" e poi sul byte "alto", ma dall'esterno questo dettaglio non e` osservabile dall'esterno (se non nel tempo richiesto per effettuare l'operazione).

Sottrazione a 8 bit e a 16 bit

L'istruzione che effettua la sottrazione è la SUB. In questo caso, siccome il primo operando è sempre l'accumulatore (a differenza della ADD, che nella versione a 16 bit può avere un primo operando diverso dall'accumulatore), il primo operando viene sempre sottinteso (indirizzamento implicito).

Abbiamo le seguenti possibilità:

        SUB 01h            ; valore immediato (qui pari a 01h): A = A - 01h
        SUB B               ; registro (B, C, D, E, H o L): A = A - B
        SUB (HL)           ; locazione di memoria puntata da HL: A = A - (HL)
        SUB (IX+11)      ; loc. di mem. puntata da IX +n: A = A - (IX+n)
        SUB (IY+1Ah)    ; loc. di mem. puntata da IY + n: A = A - (IY+1n)

Al termine, se la sottrazione ha richiesto un prestito, viene posto a uno il flag di riporto carry (che  viene usato anche come prestito, borrow).

Anche in questo caso abbiamo la variante "con il prestito in ingresso", la SBC:

        SBC A,01h    ; valore immediato (qui pari a 01h): A = A - 01h - carry
        SBC A,B      ; registro (A, B, C, D, E, H o L): A = A - B - carry
        SBC A,(HL)   ; locazione di memoria puntata da HL: A = A - (HL) - carry
        SBC A,(IX+16); loc. puntata da IX + n: A = A - (IX+n) - carry
        SBC A,(IY+n) ; loc. puntata da IY + n: A = A - (IY+n) - carry

L'unica istruzione di sottrazione a 16 bit è la sottrazione con riporto SBC con primo operando e destinazione del risultato HL:

        SBC HL, BC    ; HL = HL - BC - carry
        SBC HL, DE    ; HL = HL - DE - carry
        SBC HL, HL    ; HL = HL - HL - carry
        SBC HL, SP    ; HL = HL - SP - carry
Istruzione CP (compare)

L'istruzione CP (compare) è molto utilizzata per fare il confronto l'accumulatore A e un operando. In pratica l'istruzione effettua una sottrazione fra l'accumulatore e l'operando senza però salvare il risultato. Lo scopo della sottrazione è semplicemente quello di cambiare il valore dei flag del registro dei flag a seconda del risultato della sottrazione. Le possibilità sono (i valori numerici sono solo degli esempi):

        CP 2Ah       ; A - 2Ah
        CP B         ; A - B (registro A, B, C, D, E, H o L)
        CP (HL)      ; A - (HL)
        CP (IX+0Ah)  ; A - (IX+n)
        CP (IY+6)    ; A - (IY+n) 

Al termine dell'istruzione gli operandi, compreso quello contenuto nell'accumulatore, rimangono invariati. L'informazione utile, cioè il risultato del confronto (p.e. "A è maggiore di 2Ah") è invece memorizzata nei flag denominati Carry, Zero e Sign, secondo la seguente tabella (s indica il secondo operando):

Risultato Carry Zero Sign
A>s 0 0 0
A = s 0 1 0
A<s 1 0 1

Sign è significativo nel caso di confronto tra numeri con segno in complemento a due. Nel caso
di confronto tra numeri a 8 bit senza segno, sono importanti i flag di Carry e di Zero. Più avanti, esaminando le istruzioni di salto condizionato, capiremo come i flag rivestono una grande importanza nella programmazione assembly.

Istruzioni di incremento e decremento

Le istruzioni di incremento (INC) e di decremento (DEC) operano su un registro oppure su una locazione di memoria, ottenuta per indirizzamento indiretto (HL) o indice (IX o IY), incrementandone o decrementandone il valore di una unità.

I casi possibili sono i seguenti (per semplicità viene considerata solo l'istruzione INC, essendo la DEC perfettamente analoga):

        INC B             ; incrementa il registro (A, B, C, D, E, H o L): B = B + 1
        INC (HL)         ; incrementa la loc. indirizzata da HL: (HL) = (HL) + 1
        INC (IX+0FFh) ; incrementa la loc. puntata da IX+n: (IX+n)=(IX+n)+1
        INC (IY+0FFh) ; come sopra, col registro IY: (IY+n)=(IY+n)+1

L'incremento o decremento è sempre di una unità, e l'operazione influenza i flag di Zero e di
Sign, ma non quello di Carry. Le operazioni di incremento e decremento sono cicliche, cioè raggiunto il massimo valore (FFh) un ulteriore incremento fa ricominciare il conteggio da zero (viceversa per l'operazione DEC).

Ci sono anche istruzioni di incremento e decremento a 16 bit. Le possibilità sono le seguenti (vengono forniti solo gli esempi con la DEC essendo la INC perfettamente analoga):

        DEC BC       ; BC = BC - 1
        DEC DE       ; DE = DE - 1
        DEC HL       ; HL = HL - 1
        DEC IX       ; IX = IX - 1
        DEC IY       ; IY = IY - 1

Attenzione: purtroppo le operazioni di incremento e decremento a 16 bit, per ragioni di realizzazione hardware, non influenzano i flag, contrariamente al normale buon senso, e di questo ne dovremo tenere conto in seguito, al momento di scrivere programmi.

Moltiplicazione

Lo Z80, a differenza di altri microprocessori più moderni, non dispone di nessuna istruzione per effettuare la moltiplicazione. Dunque il prodotto può solo essere calcolato per mezzo di un programma (trasformandolo in una sequenza di somme).

precedente - successiva

Sito realizzato in base al template offerto da

http://www.graphixmania.it