Il set istruzioni dell'8051

Tutti i chip della famiglia 8051 eseguono lo stesso set di istruzioni (111 istruzioni).

II set di istruzioni è ottimizzato per applicazioni di controllo e mette a disposizione modi di indirizzamento veloci per accedere alla RAM interna; mette inoltre a disposizione la possibilità di manipolare variabili ad 1 bit.

Tutte le istruzioni vengono eseguite in 1 o 2 cicli macchina, eccetto le istruzioni di divisione (DIV) e di moltiplicazione (MUL) che richiedono 4 cicli macchina.

Un ciclo macchina è rigorosamente costituito da 12 periodi del segnale di clock. Ad esempio, se il clock è di 12 MHz un'istruzione che richiede 1 ciclo macchina viene eseguita esattamente in 1 uS.

Modi di indirizzamento
Istruzioni aritmetiche
Istruzioni logiche
Istruzioni di trasferimento dati
Istruzioni per la gestione delle tabelle dati
Istruzioni booleane
Istruzioni di salto

Modi di indirizzamento

Istruzioni aritmetiche

Le istruzioni aritmetiche sono mostrate in tabella

Cod. mnemonico Operazione Dir Ind Reg Imm Imp
ADD A,<byte> A = A + <byte> * * * *  
ADDC A,<byte> A = A + <byte> + C * * * *  
SUBB A,<byte> A = A - <byte> - C * * * *  
INC A A = A + 1         *
INC <byte> <byte> = <byte> +l * * *    
INC DPTR DPTR = DPTR + 1         *
DEC A A = A - 1         *
DEC <byte> <byte> = <byte> - l * * *    
MUL AB BA = B·A         *
DIV AB A = A div B          
  B = A mod B         *
DA Decimal Adjust(BCD)         *

La tabella indica le modalità di indirizzamento che possono essere usate per accedere agli operandi.

Le istruzioni INC <byte> e DEC <byte> permettono di incrementare e decrementare direttamente il contenuto della RAM interna senza passare attraverso I'accumulatore.

L'istruzione MUL AB effettua la moltiplicazione fra il contenuto dell'accumulatore e quello del registro B; la parte più significativa del risultato viene scritta nel registro B, la parte meno significativa nell' accumulatore.

L'istruzione DIV AB divide il contenuto dell'accumulatore per il contenuto del registro AB; il quoziente viene scritto in accumulatore e il resto nel registro B.

L' istruzione DA A serve quando si utilizza I'aritmetica in BCD.

Utilizzando la rappresentazione BCD le istruzioni ADD e ADDC dovrebbero essere sempre seguite da un'istruzione DA A; ciò assicura che il risultato sia ancora in BCD. DA A non deve essere utilizzata per convertire un numero da binario a BCD.


Istruzioni logiche

Le istruzioni logiche sono illustrate in tabella

Cod mnemonico Operazione Dir Ind Reg Imm Imp
ANL A,<byte> A = A and <byte> * * * *  
ANL <byte>,A <byte> = <byte> and A *        
ANL <byte>,#n <byte> = <byte> and n *        
ORL A,<byte> A = A or <byte> * * * *  
ORL <byte>,A <byte> = <byte> or A *        
ORL <byte>,#n <byte> = <byte> or n *        
XRL A,<byte> A = A xor <byte> * * * *  
XRL <byte>,A <byte> = <byte> xor A *        
XRL <byte>,#n <byte> = <byte> xor n *        
CLR A Azzera ACC         *
CPL A Complementa ACC         *
RL A Ruota ACC a sinistra         *
RLC A Ruota ACC a sinistra utilizzando CY         *
RR A Ruota ACC a destra         *
RRC A Ruota ACC a destra utilizzando CY         *
SWAP A Scambia i due semibyte(nibble) di ACC         *

Per quanto riguarda le modalità di indirizzamento, vale quanto detto per le istruzioni aritmetiche.
Le operazioni booleane possono essere effettuate su qualunque byte della RAM interna o della SFR area, utilizzando I'indirizzamento diretto senza passare attraverso I'accumulatore.

Esempio :

ANL 30H,#85H

effettua un AND tra il contenuto della locazione 30H della RAM interna e il numero 85H. II risultato viene posto ancora nella locazione 30H. L'accumulatore non viene utilizzato.


Istruzioni di trasferimento dati

RAM interna:

le istruzioni di trasferimento dati con la RAM interna sono illustrate in tabella.

Cod.mnemonico Operazione Dir Ind Reg Imm
MOV A,<sorg> A = <sorg> * * * *
MOV <dest>,A <dest> = A * * *  
MOV <dest>,<sorg> <dest> = <sorg> * * * *
MOV DPTR,#ind16 DPTR = ind16       *
PUSH <scr> Incrementa SP e inserisci <src> nello stack *      
POP <dest> Preleva <dest> dallo stack e decrementa SP *      
XCH A,<byte> Scambia A con <byte> * * *  
XCHD A,@Ri Scambia i semibyte bassi di A e del dato puntato da Ri(Ri può essere RO o R1)   *    

Le indicazioni <dest> e <sorg> specificano rispettivamente le locazioni destinazione e sorgente. Si tenga presente che la SFR area può essere indirizzata solo in modo diretto. L'istruzione MOV <dest>,<sorg> permette di effettuare un trasferimento dati senza passare attraverso I'accumulatore.

Per le operazioni con lo stack, lo stack pointer SP dopo un reset punta alla locazione 07H della RAM interna mentre il banco di registri RO-R7, che viene automaticamente selezionato, è il banco numero 0

Se si vuole utilizzare uno degli altri tre banchi di registri è consigliabile far puntare lo stack pointer SP oltre la zona di memoria occupata dai banchi dei registri (si tenga presente che ne11'8051 lo stack cresce verso gli indirizzi alti della memoria).


RAM esterna:

può essere soltanto utilizzata la modalità di indirizzamento indiretto. Si possono utilizzare i registri ad 8 bit R1 ed RO o il registro a 16 bit DPTR. La tabella mostra le istruzioni che permettono di accedere alla memoria esterna per i dati.

Cod.mnemonico Operazione
MOVX A,@Ri II dato puntato da Ri (R1 o RO)viene trasferito in A
MOVX @Ri,A Il dato contenuto in A viene trasferito nella locazione puntata da Ri
MOVX A,@DPTR Il dato puntato da DPTR(indirizzo a 16 bit) viene trasferito in A
MOVX @DPTR, A Il dato contenuto in A viene trasferito nella locazione puntata da DPTR

Utilizzando i registri RO ed R1 si possono indirizzare solo i primi 256 byte della RAM esterna, con il registro DPTR tutti i 64 k di memoria RAM esterna.

Si tenga presente che il microprocessore 8051 distingue tra memoria interna ed esterna grazie al fatto che il codice operativo dell'istruzione MOV è diverso dal codice operativo di MOVX (X sta per eXternal). Quando viene utilizzata I'istruzione MOVX, le linee WR e RD vengono abilitate in modo da attivare la memoria esterna.

Se l'istruzione MOVX non viene utilizzata, queste due linee rimangono inattive e sono utilizzabili come linee di I/O.


Istruzioni per la gestione delle tabelle dati

L'8051 mette a disposizione delle istruzioni con modalità di indirizzamento indicizzato per la gestione di tabelle nella memoria per i programmi.

Queste tabelle di ricerca possono essere solo lette e non modificate e possono risiedere nella memoria per i programmi esterna (nel qual caso ci pensa 1'8051 ad attivare il terminale PSEN).

Le istruzioni per la gestione di tabelle sono mostrate in tabella

Cod. mnemonico Operazione
MOVC A, @A + DPTR Il dato puntato da (A+ DPTR) viene trasferito in A.
MOVC A, @A + PC Il dato puntato da (A+ PC) viene trasferito in A

La prima istruzione MOVC può gestire una tabella a 256 punti di ingresso (256 elementi) numerati da O a 255.
La base della tabella deve essere caricata in DPTR mentre I'accumulatore funge da indice nella tabella stessa.
L'altra istruzione MOVC opera in modo analogo con la differenza che questa volta è il PC a puntare alla base della tabella.
La tabella in questo caso viene consultata per mezzo di un sottoprogramma.

Esempio :

MOV A,#5
CALL tabella

II sottoprogramma "tabella" può essere il seguente:
tabella: MOVC A,@A+PC
RET

............. (elementi della tabella)

In questo caso la tabella può avere 255 punti di ingresso (255 elementi) numerati da 1 a 255. I1 numero 0 non può essere utilizzato perché coincide con la posizione occupata dall'istruzione RET (indirizzo contenuto in PC durante I'esecuzione di MOVC) e quindi il valore ritornato dalla lettura della tabella sarebbe proprio il codice operativo dell'istruzione RET.


Istruzioni booleane

L'8051 contiene un processore completo per le operazioni booleane (cioè su singoli bit). La RAM interna contiene una zona indirizzabile bit a bit (locazioni di memoria da 20H a 2FH, 16 byte per un totale di 128 bit utilizzabili separatamente). Anche i bit delle porte di I/O e di alcuni registri sono indirizzabili separatamente.
Per le operazioni booleane il bit di riporto C del registro PSW ha la funzione di accumulatore.
Le istruzioni booleane sono mostrate in tabella

Cod. mnemonico Operazione
ANL C,bit C =C and bit
ANL C./bit C = C and not bit
ORL C,bit C = C or bit
ORL C,/bit C = C or not bit
MOV C,bit C = bit
MOV bit,C bit = C
CLR C C = O
CLR bit bit = 0
SETB C = C = l
SETB bit bit = l
CPL C C = not C
CPL bit bit = not bit
JC rel Salta se C=l
JNC rel Salta se C=O
JB bit,rel Salta se bit = 1
JNB bit,rel Salta se bit=0
JBC bit,rel Salta se bit = O e azzera bit

Gli indirizzamenti sono effettuati solo in modo diretto sia nella RAM per i dati sia nella SFR area (registri). Gli indirizzi per bit vanno da OOH a 7FH per i 128 bit posizionati nelle locazioni di memoria RAM interna da 20H a 2FH.
L'indicazione "rel" nelle istruzioni di salto condizionato indica che il salto viene effettuato in modo relativo rispetto al valore contenuto nel PC. L'offset rispetto al PC ha il formato di un byte contenente un numero con segno. I1 campo di valori di salto va quindi da -128 a +127.


Istruzioni di salto

Le istruzioni di salto incondizionato sono riassunte nella tabella

Cod. mnemonico Operazione
JMP addr Salta all'indirizzo addr
JMP @A + DPTR Salta all'indirizzo che si ottiene sommando A con DPTR
CALL addr Salta al sottoprogramma che inizia all'indirizzo addr. L'indirizzo corrente di PC viene salvato nello stack.
RET Ritorna da sottoprogramma
RETI Ritorna da interruzione
NOP Nessuna operazione

L'istruzione JMP esiste in tre formati diversi: SJMP, LJMP e AJMP.

JMP è un codice mnemonico generico che può essere usato qualora non sia rilevante quale dei tre formati venga utilizzato.

L'istruzione SJMP (Short JuMP) codifica I'indirizzo di salto con un offset relativo al PC; I'istruzione è lunga 2 byte di cui uno è utilizzato per I'offset. L'offset è dunque un numero con segno che va da -128 a + 127.

L'istruzione LJMP (Long JuMP) è lunga 3 byte di cui due sono utilizzati per I'offset. L'offset è dunque un numero con segno che va da -32768 a = +32767 che permette di saltare in qualunque posizione della memoria.

L'istruzione AJMP (Absolute JuMP) utilizza 11 bit per I'indirizzo. L'istruzione è lunga 2 byte; 3 bit del codice operativo e il rimanente byte vengono utilizzati per costruire I'indirizzo. L'indirizzo viene costruito sfruttando i 5 bit piu significativi del PC e gli 11 bit sopra menzionati. È perciò possibile effettuare un salto entro 2 k oltre l'istruzione AJMP (è quindi possibile solo un salto "in avanti").

Anche I'istruzione CALL dispone di due varianti ACALL e LCALL che dal punto di vista dell'indirizzo di salto si comportano analogamente alle istruzioni AJMP e LJMP.

L'istruzione JMP @A + DPTR permette di effettuare un salto con selezione a seconda del valore contenuto nell'accumulatore. L' indi rizzo di salto viene calcolato sommando il contenuto del registro DPTR a quello dell'accumulatore.

Generalmente DPTR viene impostato con I'indirizzo di inizio di una tabella di salti e I'accumulatore viene utilizzato come indice di questa tabella.

Si supponga di avere una tabella di salti (tabella_salti) a 5 elementi; il codice per utilizzare questa tabella potrebbe essere il seguente:

MOV DPTR,#tab_salti
MOV A,#numero salto
RL A
JMP @A+DPTR

tab_salti:

AJMP ind 1
AJMP ind 2
AJMP ind 3
AJMP ind 4
AJMP ind 5

L'istruzione RL A serve per convertire I'indice che va da O a 4 in un numero pari che va da O a 8; infatti ogni elemento della tabella di salti è lungo 2 byte.

Per quanto riguarda invece i salti condizionati le istruzioni messe a disposizione da11'8051 sono riportate qui in tabella

Cod. mnemonico Operazione Dir Ind Reg lmm Imp
JZ rel Salta se A = 0         *
JNZ rel Salta se A <> 0         *
DJNZ <byte>,rel Decrementa <byte>e salta se <byte> <> 0 *   *    
CJNE A,<byte>,rel Salta se A <> <byte> *     *  
CJNE <byte>,#n,rel Salta se A <> n   * *    

Benché non esista un flag di zero nel registro di stato PSW, le istruzioni JZ e JNZ funzionano controllando direttamente il contenuto dell' accumulatore.