Tutorials - PIC18 by Data Sheet

 

Pag 68-69

 


Indirizzamento indiretto post-incrementato

 

Con una struttura simile al C (e nell’ intento di fornire un supporto molto efficiente a questo linguaggio), gli enhanced dispongono di una modalità di indirizzamento che auto incrementa il puntatore dopo aver effettuato l’ operazione desiderata.


Viene usata una istruzione specifica : 

POSTINCx

dove x è l’ indice (0, 1 o 2) dell’ INDF usato. 

La sintassi è semplice :

lsfr FSR2, target    ; puntatore su target
movf POSTINC2, w     ; legge dato in W e incrementa il puntatore

Nulla vieta di utilizzare tanto l’ indirizzamento indiretto semplice che quello incrementato nello stesso momento. Ad esempio, si vuole muovere il contenuto delle locazioni target e target+1 rispettivamente nei registri W e deposito1, che sta in un banco qualunque non indicizzato dai BSR :

lsfr  FSR2, target      ; puntatore su target
movf  POSTINC2, w       ; legge dato in W e incrementa puntatore
movff INDF2, deposito1  ; muove target+1 a deposito1   

In sostanza, la prima riga posiziona il puntatore su target.
La seconda riga copia in W il contenuto di target e , nello stesso tempo, incrementa FSR2

La terza riga sposta il contenuto di target+1, puntato ora da FSR2, nella locazione deposito1; essendo una movff a 32bit, non ci sono limiti negli indirizzamenti.

Da questi semplici esempi si può notare come il set di istruzioni e la struttura degli enhanced li rendano decisamente superiori e innovativi rispetto ai mid renge.

Un esempio più complesso può essere il seguente : copiare 128 variabili dal Banco1 al Banco2. Se nei mid range si trattava di districarsi in un groviglio di puntatori, indici, banchi, negli enhanced la cosa si risolve con :

start  equ  0x100           ; inizio del Banco1
destin equ  0x200           ; inizio del Banco2

  lsfr  FSR0, start         ; puntatore su target
  lsfr  FSR1, destin        ; puntatore su target
  movff POSTINC0,POSTINC1   ; sposta dato da start a destin
  btfss FSR0L, 7            ; mossi 80h dati ?

   bra  loop                ; no - un altro loop
  ....                      ; si - prosegui 
  ....                      ; con le successive istruzioni  

Se ci sono dubbi sulla riga btfss FSR0L, 7 questo test serve a determinare quando il bit 7 del puntatore low ha raggiunto 80h (128 dec.), ovvero la fine del loop (FSRH rimane sempre a zero).

Si poteva fare il test anche su FSR2L, che aumenta nella stessa misura.

Non c'è nessuna limitazione del numero di puntatori che si possono utilizzare contemporaneamente in una struttura logica. Ad esempio, lo spostamento di un' area di memoria in un' altra diventa estremamente semplice. 

Ad esempio, vogliamo spostare l' intero contenuto del banco 3 nel banco 4 :

lfsr  FSR0,0x300        ; FSR0 punta sul banco 3
lfsr  FSR1,0x400        ; FSR1 punta sul banco 4
loop:
movff POSTINC0,POSTINC1 ; sposta un byte
btfss FSR0H, 2          ; FSR0 = 0x400 ?
bra   loop              ; no, loop

Estremamente semplice, dato che l' avanzamento degli indici di puntamento avviene automaticamente e i registri virtuali POSTINCx (come pure POSTDECx , INDFx e FSRx) sono trattabili come qualsiasi altro registro. Il test che chiude il loop deriva dal fatto che, come, abbiamo detto prima, gli FSR sono composti da due bytes, una parte alta, FSRxH ed una bassa, FSRxL. 

Quindi , l' istruzione :

lfsr  FSR0,0x300

ha caricato 00h in FSR0L e 03h in FSR0H.
Ogni incremento o decremento, agisce sul registro ballo (FSRxL), all' azzeramento del quale viene modificato il registro alto (FSRxH), come avviene in un normale contatore a 16 bit. 

Per cui, ad esempio :

lfsr  FSR0,0x3FE        ; FSR0L= FEh FRS0H=03h
movf  POSTINC0,w        ; FSR0L= FFh FRS0H=03h
movf  POSTINC0,w        ; FSR0L= 00h FRS0H=04h
movf  POSTINC0,w        ; FSR0L= 01h FRS0H=04h

Questa struttura a 16 bit permette di indirizzare con gli FSR tutta l' area della memoria RAM e quindi non esiste più un meccanismo come quello dell' IRP che è necessario sui PIC16.

 


Indirizzamento indiretto post-decrementato  

In modo del tutto speculare a quanto appena visto, esiste una istruzione POSTDECx che decrementa automaticamente il puntatore una volta eseguita l’ istruzione voluta.
Analogamente all’ esempio precedente, spostiamo il contenuto di target in W e di target-1 in deposito1    

lsfr  FSR2, target     ; puntatore su target
movf  POSTDEC2, w      ; legge dato in W e decrementa puntatore
movff INDF2, deposito1 ; muove target-1 a deposito1 

In sostanza, la prima riga posiziona il puntatore su target.
La seconda riga copia in W il contenuto di target e , nello stesso tempo, decrementa FSR2

La terza riga sposta il contenuto di target-1, puntato ora da FSR2, nella locazione deposito1.

Un altro esempio:

cblock source1
       source2
endc
cblock target1
       target2
endc
....
....
lsfr   FSR2, source2      ; punta FSR2 su source2
movff  POSTDEC2, target2  ; carica contenuto di source2
                          ; in target2

il che permette di fare anche :

lsfr   FSR2, source2      ; punta FSR2 su source2
movff  POSTDEC2, target2  ; carica contenuto di source2
                          ; in target
movff  INDF2, target1     ; e il contenuto di source1 in
                          ; traget1

in quanto il primo movff POSTDEC2  ha fatto si che il puntatore FSR2 sia diminuito di uno, puntando quindi a source1.

uesto indirizzamento consente di muoversi all' indietro in una tabella o un array di dati


Indirizzamento indiretto pre-incrementato

Esiste anche un indirizzamento in cui l’ incremento del puntatore avviene prima dell’ esecuzione dell’ istruzione e fa capo al codice PREINCx.
Un esempio :

lsfr  FSR0, start     ; puntatore su start a 0x0100
movf  PREINC0, w      ; legge dato start+1 (0x101) in W  

Questo indirizzamento permette di di utilizzare un puntatore che sia antecedente alla locazione da puntare.


NOTA:
             Non esiste una modalità pre-decrementata

 



Indirizzamento indiretto indicizzato  

Questa modalità fa uso del registro WREG come di un indice del puntatore, per cui questo sistema di indirizzamento è chiamato anche “Plus W”. Ed è appunto PLUSW che si chiama l’ istruzione relativa.

La base sono sempre i registri FSRx, a cui W viene sommato come indice :

lsfr  FSR2, target    ; puntatore su target
movlw 5               ; indice w = 5
movf  PLUSW2, w       ; legge dato da target+5 in W

Da notare la possibilità di vari “giochini”, come ad esempio, supponendo che target +5 contenga 20h :

lsfr  FSR2, target    ; puntatore su target
movlw 5               ; indice w = 5
movf  PLUSW2, w       ; legge dato da target+5 in W (w = 20)
movf  PLUSW2, w       ; legge dato da target+25 in W

In questa modalità, si può indirizzare un’ area di 7Fh attorno alla locazione puntata, in quanto il contenuto di W viene considerato come un valore con segno, per cui se il bit 7 è a 1, il valore è negativo (e viene sottratto).
In altre parole, valori di W superiori a 0x7F saranno presi come negativi.

lsfr   FSR2, 0x434        ; punta FSR2 su 0x434
movlw  0x85               ; w = -0x7B
movf   PLUSW2, w          ; in w il contenuto di 0x454


Questo indirizzamento consente di stabilire, ad esempio, quale elemento di un array prelevare, ponendo l' indice in W,

Ovviamente ogni PLUSWx corrisponde ad un FSRx.

In questa struttura, l' indirizzo della variabile puntata è esso stesso una variabile e permette di lavorare su variabili il cui indirizzo relativo può essere calcolato, rendendo possibili operazioni assai complesse.



 

 

 

Copyright © afg. Tutti i diritti riservati.
Aggiornato il 03/12/10.