COMPUTED
GOTO
E' comune in programmi in cui gli algoritmi operano scelte tra
diverse possibilità, il trovarsi a dover gestire salti a destinazioni
dipendenti da una variabile.
Una tecnica è quella dei salti programmati, possibile sia sui
mid-range che sugli enhanced col sistema delle lookup tables:
; Prendi
un valore da tabella in funzione
; di una variabile offset
movf offset, W ;
salva la variabile in w
call TABLE ;
chiamata della tabella dei salti
....
ORG nn00h
TABLE
addwf PCL
retlw nnh
; ritorna col valore scelto
retlw mmh
....
Il valore tabellato per la variabile scelta viene
prelevato aggiungendo al PC un offset dipendente dalla variabile stessa.
La tabella dei valori di ritorno (TABLE) è formata da una sequenza di RETLW con
cui WREG rientra caricato con il valore stesso.
L' istruzione di accesso alla tabella è una CALL, ovvero una chiamta a
subroutine, che rientrerà all' istruzione successiva a seguito di un RETURN o
RETLW.
L' offset, caricato in WREG, verrà sommato al PC (ADDWF PCL) per costringere un
salto al punto desisderato della tabella.
Va osservato che:
-
il numero delle scelte possibili è 255, massima
estensione del WREG a 8 bit
m
-
la TABLE deve iniziare in un' area che sia a indirizzo
xx00h, per evitare la necessità di calcolare anche i valori di PLATH /
PCLATU
-
siccome l' ampiezza dell' istruzione RETLW degli enhanced
è 2 bytes, sarà necessario che anche l' offset si muova di
conseguenza, ad esempio moltiplicandolo per 2 con uno shift
Il metodo delle lookup tables può essere impiegato anche nel
caso di tabelle che rinviino non tanto a valori quanto a destinazioni.
Ad
esempio, ecco come può essere strutturata una gestione di branch multipli
dipendenti da una variabile, da 0 a 255 selezioni, senza i vicoli di pagina del
metodo precedente:
;
Esegui la routine n
movf n, W
; variabile in w
movwf routn
; e salva in routn
call TABLE
;
chiamata della tabella dei salti
....
TABLE
movlw HIGH (tablejump) ; indirizzo alto
della tabella
movwf PCLATH
; in PCLATH
rlcf routn,
w ;
moltiplica per 2
btfsc STATUS, C
;
>127 ?
incf PCLATH,
f ; si - PCLATH
+ 1
addlw LOW (tablejump) ; indirizzo
basso della tabella
btfsc STATUS, C
;
over ?
INCF PCLATH,
f ; si PCLATH +
1
movwf PCL
; provoca il salto controllato
; tabella dei salti
tablejump
bra sub0
bra sub 1
bra sub2
.....
return
; routines chiamate
sub0
.....
return
sub1
.....
return
Questo
metodo consente di posizionare le routines in qualunque parte della memoria, non
importa dove, sfruttando la singola paginazione della memoria programma
degli enhanced.
Se la distanza tra la tabella e le routines è elevata, si sostituiranno
i BRA con dei GOTO, avendo cura di moltiplicare l' offset per 4
invece che per 2 (GOTO è a 32 bit).
Da notare che la linea RLCF
non necessita di un valore particolare del Carry impostato prima, dato che
questo passa al bit 0. Ma il bit 0 del PC è sempre forzato a 0 dal
meccanismo che prevede istruzioni solo con un numero pari di bytes. Per contro,
il Carry andrà considerato se si operano due shift per la
moltiplicazione per 4.
La stessa struttura può essere
utilizzata per effettuare salti invece di accessi a subroutines, sostituendo il CALL
TABLE con un BRA TABLE o un GOTO TABLE e non terminando
le strutture chiamate con un RETURN.
Si può anche
utilizzare lo stesso metodo per rientrare semplicemente con un valore in WREG
attraverso il RETLW, ma bisogna ricordare che, causa la struttura a due bytes
delle istruzioni, un byte andrà perso per ogni valore tabellato.
Se
la tabella contiene meno di 127 elementi, si potranno eliminare le righe
btfsc STATUS, C
;
>127 ?
incf PCLATH,
f ; si - PCLATH
+ 1
NOTA:
Metodi di questo genere sono mediati dai mid-range e gli enhanced,
anche in questo caso, risolvono brillantemente la situazione utilizzando
un gruppo di istruzioni di lettura e scrittura di tabelle, molto potenti e
versatili.
|