Due opcodes consentono il ritorno da una chiamata a subroutine e uno il
rientro da un interrupt.
Sappiamo che, nei PIC, il Program
Counter avanza a seconda dell' istruzione incontrata, scandendo la
lista del programma in modo automatico.
Però è possibile manipolarne il valore per far si che l' istruzione
successiva non sia quella prevista dall' automatismo, ma un' altra.
In particolare, una subroutine devia l' esecuzione dal flusso principale in un
"ramo" differente, dal quale occorre poi rientrare al main.
L'istruzione CALL in sostanza non fa che modificare il contenuto del Program
Counter con l'indirizzo oggetto dell'istruzione e, contemporaneamente, salvare
il contenuto del Program Counter nello stack.
Dato che abbiamo modificato il PC, l' esecuzione passa al nuovo indirizzo
puntato e vengono eseguite le istruzioni di questa area. Alla fine di quanto
previsto, occorre una azione contraria a quella della CALL.
Ovvero, nel Program Counter vie forzato l'indirizzo preso dallo stack, di modo
che l'escuzione riprenda al punto del main in cui era stata sospesa.
La funzione delle istruzioni RETURN e RETLW è proprio questa: recuperare
l'indirizzo di rientro dallo stack e chiudere l'esecuzione della subroutine.
RETURN o RETLW ?
Ci si può chiedere se ci sia una preferenza nell' uso di RETURN piuttosto
che di RETLW.
Dal punto di vista dell' esecuzione da parte dell' ALU, entrambi gli opcode
sono identici; sono eseguiti nello stesso tempo e riportano il PC
all'indirizzo salvato nello stack. Quindi, l'uso di uno piuttosto che dell'
altro è indifferente.
Da un punto di vista logico la differenza consiste nel diverso trattamento
del registro W.
Nei Baseline, core a 12 bit, RETLW è l'unico meccanismo di
ritorno da una subroutine (ricordiamo che nei Baseline non esistono interrupt
e l'uscita dalla modalità sleep provoca un reset).
RETLW carica in W il valore in oggetto, ovvero modifica il contenuto di W.
Questa azione è indispensabile nelle tabelle RETLW e può rivelarsi utile per
evitare un movlw in uscita dalla subroutine, assegnando un valore determinato
a W.
In particolare, il compilatore dell' Assembler MPASM, adegua quanto scritto
nel sorgente all' ambiente di compilazione. Così, se scriviamo RETURN in un
sorgente destinato ad un Baseline, MPASM provvederà a compilare l'opcode
RETLW 0, inviando un Warning [227] e il messaggio esplicativo
Substituting RETLW 0 for RETURN pseudo-op.
Questo consente di usare indifferentemente RETURN o RETLW in sorgenti
compilabili su Baseline o Midrange.
Però, se è necessario conservare il contenuto di W al ritorno dalla
subroutine, l' uso di RETLW richiede che W sia salvato in un registro temporaneo e
poi ripristinato dopo il ritorno al programma principale, il che è certo
scomodo.
Dai Midrange in su è introdotto RETURN, che non modifica il contenuto di W.
Attenzione perchè come detto all' inizio, l'esecuzione dei due opcode è
identica come attività dell' ALU e quindi come tempo, per cui il RETLW che
carica un numero in W impiega lo stesso tempo di RETURN che non carica
alcunchè.
Dunque, l'impiego di una o dell'alta istruzione dipende solamente dalle
necessità del programma. Se salvare il contenuto di W non ha importanza,
RETURN o RETLW n sono indifferenti.
RETFIE ?
Anche il meccanismo di rientro da un interrupt è del tutto identico a
quello di rientro da una subroutine. In entrambi i casi occorre ripristinare
il PC prelevando dallo stack l'indirizzo.
In questo senso, RETFIE, RETLW e RETURN sono identici.
C'è, però, una fondamentale differenza: la chiamata di un interrupt
richiede che ulteriori chiamate successive non possano essere eseguite fino a
che non è stata portata a termine quella corrente. Anche nei PIC18F, dove
esiste un interrupt a due livelli di priorità, nessun interrupt può
interroperne un altro dello stesso livello. Questo si ottiene con un
meccanismo che disabilita la funzione, la quale viene riabilitata al rientro
dall' interrupt, permettendo così di servire i successivi.
RETFIE, oltre al ri posizionamento del PC, contiene anche questa funzione.
Ne deriva che non è possibile usare al suo posto RETURN o RETLW, dato che
con questi non sarebbe più possibile avere chiamate di interrupt. Ne' è
possibile usare RETFIE come ritorno da una subroutine, dato che si avrebbe una
non richiesta attivazione del sistema di interrupt.
Argomenti collegati:
|