ELEMANIA
Z80 - Istruzioni di salto
Istruzioni di salto

Se non esistessero le istruzioni di salto (jump), i programmi sarebbero sempre eseguiti nello stesso modo, sequenzialmente, e non sarebbero molto utili. Questo tipo di istruzioni è infatti importantissimo, dal momento che consente al programmatore di alterare in maniera controllata ed esplicita la sequenza di esecuzione del programma, come si può fare nei linguaggi ad alto livello (con l'istruzione GOTO). Il controllo dell'esecuzione può, grazie ad una istruzione di salto, essere passato da una parte all'altra del programma.

Le istruzioni di salto agiscono sul contenuto del Program Counter (PC), registro interno che, come si è visto in precedenza, è responsabile della sequenza di esecuzione delle istruzioni (contiene al proprio interno l'indirizzo in memoria della successiva istruzione da eseguire).

Salto incondizionato

Il salto è detto incondizionato quando avviene sempre e non dipende dal verificarsi o meno di una certa condizione. Vediamo subito un esempio:

       JP 2000h       ; salta all'indirizzo in memoria 2000h (16 bit)

L'esecuzione di questa istruzione produce l'assegnazione del valore dell'indirizzo (2000h nell'esempio) al Program Counter, e quindi il prelievo della successiva istruzione sarà eseguito non più dalla locazione successiva a quella della istruzione corrente, ma dalla locazione all'indirizzo specificato. Vediamo tutto questo più concretamente considerando il seguente spezzone di programma in assembly:

Indirizzo Istruzione Commento
10FFh LD A,B ;istruzione precedente (qualsiasi istruzione)
1100h JP 2000h ;salta alla locazione 2000h
1103h NOP ;non viene eseguita (il µP salta a 2000h)
... ...  
2000h CP B ;l'esecuzione prosegue da questa istruzione
       

In pratica, nell'esempio precedente, tutte le istruzioni comprese fra 1103h e 2000h vengono ignorate dal µP. Si noti che l'indirizzo dell'istruzione JP è 1100h, mentre l'indirizzo dell'istruzione successiva è 11003h. La ragione è che l'istruzione JP occura 3 byte, uno per il codice operativo (C3) e due per l'operando a 16 bit (in ordine inverso come al solito, JP 2000h corrisponde a C30020h).

Quando si usano istruzioni di salto risulta particolarmente comodo l'utilizzo di etichette, per evitare di doversi calcolare gli indirizzi (in questo modo il calcolo viene fatto automaticamente dall'assemblatore, che si occupa di sostituire le etichette con gli indirizzi corrispondenti). Per esempio il programma precedente, scritto usando le etichette diventa:

            LD A, B       ; istruzione precedente (qualsiasi istruzione)
            JP AVANTI     ; salta fino all'etichetta AVANTI
            NOP           ; non viene eseguita
            ...
AVANTI:     CP B          ; l'esecuzione prosegue da questa istruzione

Quando il salto avviene a un indirizzo di memoria successivo (più alto) si parla di salto in avanti; viceversa si ha il salto all'indietro. Come esempio di salto all'indietro si consideri questo spezzone di programma:

            ADD A,D       ; istruzione precedente (qualsiasi istruzione)
CICLO:      LD B, A       ; questa è l'istruzione su cui "si salta"
            ADD A,D       ; prosegue il codice
            ...
            JP CICLO      ; salta a CICLO

Questo è un esempio di ciclo infinito: a causa del salto all'indietro alla locazione CICLO, verranno ripetute all'infinito le istruzioni comprese tra l'etichetta CICLO ed il salto JP CICLO.

Un ciclo infinito ha generalmente scarsa rilevanza pratica, eccetto che in pochi casi: per esempio quando si vuole che un programma ripeta sempre uno stesso gruppo di operazioni, fino allo spegnimento fisico del sistema. Vedremo più avanti come una Interruzione (Interrupt) permetterà al microprocessore di uscire da un ciclo infinito, e andare ad eseguire un altro programma.

 

Salto condizionato

I tipi di salto più importanti dal punto di vista computazionale sono quelli condizionati. Questi salti sono eseguiti o no dal processore a seconda dello stato di una ben precisa condizione e permettono al µP di prendere "decisioni". La sintassi generale di un'istruzione di salto condizionato è:

JP <condizione>,<indirizzo>

ome nei salti incondizionati, anche qui l'indirizzo indica la locazione a cui saltare, mentre la <condizione> determina se il salto può essere effettuato o no. Scopriamo finalmente a cosa servono i flag del flag register: la <condizione> di cui si parla è infatti fornita unicamente dallo stato logico dei flag.

Tra le varie condizioni possibili, ne vediamo solo alcune, quelle più usate:

            JP C, 11A0h     ;salta alla locazione 11A0h se Carry = 1
            JP NC,3F00h    ;salta alla locazione 3F00h se Carry = 0
            JP Z, 1F00h     ;salta alla loc.ne 1F00h se il Flag di Zero = 1
                                ;(cioč se il risultato precedente e` stato ZERO)
            JP NZ,8000h    ;salta alla loc.ne 8000h se il Flag di Zero = 0
                                ;(cioč se il ris. prec. e` stato NON ZERO)
            JP P, 00FFh    ; salta se il  risultato dell'ultima operazione č positivo
                                 (cioč se il flag del segno S č uguale a zero)
            JP M,34A0h    ; salta se il risultato dell'ultima operazione č negativo
                                 (cioč se il flag del segno S č uguale a uno)


Il salto viene eseguito solo se la condizione è verificata, in caso contrario il processore prosegue con l'istruzione successiva a quella del salto, come se niente fosse successo. Per un elenco completo delle condizioni possibili si rimanda alla tabella riassuntiva delle istruzioni.

 

Salti assoluti e salti relativi

Gli esempi presentati finora, che fanno uso dell'istruzione JP, sono tutti salti assoluti, nel senso che l'istruzione specifica l'indirizzo completo della locazione di memoria a cui si vuole saltare.

Un'altra categoria di istruzioni di salto è quella dei cosiddetti salti relativi (JR). In questo caso non viene fornito l'indirizzo assoluto a cui saltare, ma il salto viene specificato relativamente all'indirizzo dell'istruzione corrente. Vediamo un esempio:

       JR 15     ; salta all'istruzione contenuta all'indirizzo PC+15
                   ; cioè l'indirizzo corrente di PC incrementato di 15

Il valore costante che accompagna l'istruzione JR (15 nell'esempio precedente) è detto offset ed è un numero a 8 bit rappresentato in complemento a due, cioè con segno. In pratica l'offset può assumere tutti i valori compresi fra -128 (all'indietro) e +127 (in avanti). Ciò restringe l'ampiezza dell'area di memoria a cui è possibile saltare con una JR a solo 256 locazioni intorno a quella corrente.

Il vantaggio di usare salti relativi, invece di quelli assoluti, è che in questo modo il codice prodotto risulta rilocabile, cioè può essere spostato in differenti locazioni di memoria ed essere eseguito correttamente. Inoltre l'istruzione JR occupa meno byte (avendo un operando a 8 bit invece di 16). La tabella mostra un confronto fra le due istruzioni

  Assoluto Relativo

Istruzione

JP

JR

Lunghezza operando

16 bit

8 bit

Lunghezza istruzione

3 byte

2 byte

Destinazione

ovunque

128 bytes prima o dopo

Come per il salto assoluto, anche il salto relativo può essere condizionato, come mostrano gli esempi seguenti:

            JR C, -8     ;salta alla locazione PC-8 se Carry = 1
            JR NC,-8     ;salta alla locazione PC-8 se Carry = 0
            JR Z, 16     ;salta alla loc.ne PC+16 se il Flag di Zero = 1

Come nel salto assoluto, anche in quello relativo risulta molto conveniente l'uso di etichette nella scrittura del programma (in questo caso è l'assemblatore che si occupa di calcolare l'offset):

            ADD A,D       ; istruzione precedente (qualsiasi istruzione)
CICLO:   LD B, A       ; questa è l'istruzione su cui "si salta"
            ADD A,D       ; prosegue il codice
            ...
            JR CICLO      ; salta a CICLO (con un salto relativo)

Un'istruzione di salto relativo un po' particolare è la DJNZ. Questa istruzione fa riferimento al registro B, lo decrementa ed effettua il salto all'indirizzo relativo specificato se B è diverso da zero. Si tratta di un'istruzione particolarmente comoda per scrivere cicli usando il registro B come contatore. Si consideri ad esempio il seguente ciclo di ritardo scritto usando la DJNZ:

               LD B,200     ; carica il valore 200 in B
RIPETI:     DJNZ RIPETI  ; continua a decrementare finché B diventa zero

 

precedente - successiva

Sito realizzato in base al template offerto da

http://www.graphixmania.it