Le
istruzioni nella memoria programma
Può essere di una certa importanza anche il conoscere come i
codici binari delle istruzioni siano conservati nella memoria programma.
Come abbiamo accennato, la lunghezza delle istruzioni del set
enhanced è pari, cioè due o 4 bytes. Non esistono istruzioni che occupano un
numero dispari di bytes. Per questa ragione il program counter avanza a passi di
due bytes, muovendosi solo tra gli indirizzi pari.
Questo indica che, nel caso si forzi il contenuto del PC, sarà
necessario curare che sia evitato l' indirizzamento di registri che contengono
la seconda parte di una istruzione.
Le istruzioni sono immagazzinate in memoria in modo che il byte
basso sia ad un indirizzo pari, mentre il byte alto ad un indirizzo dispari.
Ad esempio, la sequenza:
movlw 55h
goto 0006h
movff 123h, 456h
sarà in memoria in questo modo:
Da notare che sia il GOTO che la MOVFF sono istruzioni a
4 bytes.
Il set enhanced ha 4 istruzioni a 4 bytes:
In tutti i casi, la seconda word dell' istruzione ha sempre la
sequenza 1111 nei primi bit più significativi, mentre gli altri 12 bit sono
occupati da dati literal, usualmente un indirizzo di memoria.
Questa scelta non è arbitraria, ma deriva dal fatto che una
istruzione che inizi con questa configurazione di bit viene interpretata come
un NOP.
La conseguenza immediata è che se l' istruzione a 4 bytes viene eseguita
correttamente, ovvero con la sequenza del PC che punta prima alla codifica, i
bytes successivi saranno interpretati come dati relativi a quella ccodifica.
Se viene indirizzato il PC sulla seconda word dell' istruzione, essa viene
interpretata ed eseguita come un NOP, senza creare gravi problemi al meccanismo
di decodifica. Questo capita sia per i test-and-branch, in cui il test, se
positivo, porta al salto dell' istruzione seguente, considerata però solo a due
bytes.
Il foglio dati propone un esempio pratico di questa situazione:
Vediamo che nel CASE 1 la prima riga TSFSZ salta, se eseguita, la
prima istruazione successiva a 2 bytes.
Ma in questo caso la prima istruzione successiva è a 4 bytes e lo skip cade
sulle seconde words dell' istruzione, che, considerate come un NOP,
producono solamente l' impegno di 2 cicli del test eseguito.
Nel CASE 2, se il test non produce il salto, la MOVFF
viene eseguita come tale.
Proviamo a chiarire ulteriormente questo punto.
Immaginiamo di avere la sequenza:
btfsc STATUS, C ; test per Carry clear
bra correct
; no - vai alla correzione
movf nocorrect
; si - non serve correzione
Se C = 0 la prima linea fa si che PC = PC + 2 + 2, ovvero a
puntare 2 locazioni più avanti, dove si trova la movf.
Se C = 1 il test non viene superato e e il PC punta sull' istruzione successiva,
ovvero il bra, che sarà eseguito.
Immaginiamo ora che correct sia a distanza superiore alle
possibilità di salto del bra e sia richiesto un goto.
btfsc STATUS, C ; test per Carry clear
goto correct
; no - vai alla correzione
movf nocorrect
; si - non serve correzione
Se C = 1 il test non viene superato e il PC punta sull'
istruzione successiva, ovvero al goto, che sarà eseguito correttamente.
Infatti la situazione dell' istruzione goto a 4 bytes è la seguente.
2
bytes istruzione btfsc
2 bytes prima metà dell' istruzione goto
2 bytes seconda metà dell' istruzione goto
2 bytes istruzione movf
e il PC, avanzando di due bytes, si porta alla prima metà dell'
istruzione goto e poi alla seconda metà.
Se C = 0 la prima linea fa si che PC = PC + 2 + 2, ovvero a puntare 2 locazioni
più avanti, cioè a metà dell' istruzione goto.
2
bytes istruzione btfsc
2 bytes prima metà dell' istruzione goto
2 bytes seconda metà dell' istruzione goto
2 bytes istruzione movf
Siccome la seconda metà dell' istruzione goto, se presa
separatamente dalla prima metà, appare alla decodifica delle istruzioni come un
NOP:
2
bytes istruzione btfsc
2 bytes prima metà dell' istruzione goto
2 bytes NOP
2 bytes istruzione movf
sarà questo NOP ad essere eseguito, per poi passare alla riga
successiva del movf.
Il risultato è che il meccanismo del PC è unico qualsiasi sia
la lunghezza delle istruzioni. Unica conseguenza è che la btfsc impiega 1 ciclo
se non eseguita, due cicli se eseguita su una istruzione successiva a due bytes
e tre cicli se l' istruzione successiva è a 4 bytes.
Questo va considerato nelle routine in cui è necessario
calcolare i tempi di esecuzione.
NOTE:
- la codifica ufficiale dell' istruzione NOP è b'0000 0000 0000
0000', ma la logica di decodifica delle istruzioni considera un NOP
anche b'1111 xxxx xxxx xxxx", ovvero la seconda metà di una
istruzione a 32 bit
- La memoria programma non inizializzata ha il massimo delle
probabilità di contenere FFh.
In tal caso, eseguendo il contenuto di queste locazioni come se
fossero istruzioni, gli enhanced eseguiranno, senza arrestarsi,
dei
NOP (mentre i mid-range eseguono degli ADDLW).
|