Sistemi integrati - Istruzioni
Il flusso del programma procede in modo sequenziale, da un'istruzione all'istruzione successiva, a meno che non venga eseguita un'istruzione di trasferimento del controllo. I vari tipi di istruzioni di trasferimento del controllo in linguaggio assembly includono salti condizionali o incondizionati e istruzioni di chiamata.
Istruzioni per loop e salti
Looping nell'8051
La ripetizione di una sequenza di istruzioni un certo numero di volte viene chiamata a loop. Un'istruzioneDJNZ reg, labelviene utilizzato per eseguire un'operazione di loop. In questa istruzione, un registro viene decrementato di 1; se non è zero, allora 8051 salta all'indirizzo di destinazione a cui fa riferimento l'etichetta.
Il registro viene caricato con il contatore del numero di ripetizioni prima dell'inizio del ciclo. In questa istruzione, sia il decremento dei registri che la decisione di saltare sono combinati in un'unica istruzione. I registri possono essere uno qualsiasi di R0 – R7. Il contatore può anche essere una posizione della RAM.
Esempio
Multiply 25 by 10 using the technique of repeated addition.
Solution- La moltiplicazione può essere ottenuta aggiungendo ripetutamente il moltiplicatore, tante volte quanto il moltiplicatore. Per esempio,
25 * 10 = 250 (FAH)
25 + 25 + 25 + 25 + 25 + 25 + 25 + 25 + 25 + 25 = 250
MOV A,#0 ;A = 0,clean ACC
MOV R2,#10 ; the multiplier is replaced in R2
Add A,#25 ;add the multiplicand to the ACC
AGAIN:DJNZ R2,
AGAIN:repeat until R2 = 0 (10 times)
MOV R5 , A ;save A in R5 ;R5 (FAH)
Drawback in 8051 - Azione in loop con l'istruzione DJNZ Reg labelè limitato solo a 256 iterazioni. Se non viene eseguito un salto condizionale, viene eseguita l'istruzione successiva al salto.
Loop all'interno di un loop
Quando usiamo un loop all'interno di un altro loop, è chiamato a nested loop. Vengono utilizzati due registri per contenere il conteggio quando il conteggio massimo è limitato a 256. Quindi utilizziamo questo metodo per ripetere l'azione più volte di 256.
Example
Scrivi un programma per -
- Caricare l'accumulatore con il valore 55H.
- Completa l'ACC 700 volte.
Solution- Poiché 700 è maggiore di 255 (la capacità massima di qualsiasi registro), vengono utilizzati due registri per contenere il conteggio. Il codice seguente mostra come utilizzare due registri, R2 e R3, per il conteggio.
MOV A,#55H ;A = 55H
NEXT: MOV R3,#10 ;R3 the outer loop counter
AGAIN:MOV R2,#70 ;R2 the inner loop counter
CPL A ;complement
Altri salti condizionali
La tabella seguente elenca i salti condizionali usati in 8051 -
Istruzioni | Azione |
---|---|
JZ | Salta se A = 0 |
JNZ | Salta se LA ≠ 0 |
DJNZ | Decrementa e salta se registro 0 |
CJNE A, dati | Salta se A ≠ dati |
CJNE reg, #data | Salta se byte ≠ dati |
JC | Salta se CY = 1 |
JNC | Salta se CY ≠ 1 |
JB | Salta se bit = 1 |
JNB | Salta se bit = 0 |
JBC | Salta se bit = 1 e cancella bit |
JZ (jump if A = 0)- In questa istruzione viene verificato il contenuto dell'accumulatore. Se è zero, l'8051 salta all'indirizzo di destinazione. L'istruzione JZ può essere utilizzata solo per l'accumulatore, non si applica a nessun altro registro.
JNZ (jump if A is not equal to 0)- In questa istruzione, il contenuto dell'accumulatore viene verificato per essere diverso da zero. Se non è zero, l'8051 salta all'indirizzo di destinazione.
JNC (Jump if no carry, jumps if CY = 0)- Il bit di flag Carry nel registro flag (o PSW) viene utilizzato per decidere se saltare o meno l '"etichetta JNC". La CPU guarda il carry flag per vedere se è sollevato (CY = 1). Se non viene sollevato, la CPU inizia a prendere ed eseguire istruzioni dall'indirizzo dell'etichetta. Se CY = 1, non salterà ma eseguirà l'istruzione successiva sotto JNC.
JC (Jump if carry, jumps if CY = 1) - Se CY = 1, salta all'indirizzo di destinazione.
JB (jump if bit is high)
JNB (jump if bit is low)
Note - Va notato che tutti i salti condizionali sono salti brevi, ovvero l'indirizzo del target deve essere compreso tra –128 e +127 byte del contenuto del contatore del programma.
Istruzioni di salto incondizionato
Ci sono due salti incondizionati nell'8051 -
LJMP (long jump)- LJMP è un'istruzione a 3 byte in cui il primo byte rappresenta il codice operativo e il secondo e il terzo byte rappresentano l'indirizzo a 16 bit della posizione di destinazione. L'indirizzo di destinazione a 2 byte consente di passare a qualsiasi posizione di memoria da 0000 a FFFFH.
SJMP (short jump)- È un'istruzione a 2 byte in cui il primo byte è il codice operativo e il secondo byte è l'indirizzo relativo della posizione di destinazione. L'indirizzo relativo va da 00H a FFH che è diviso in salti in avanti e indietro; vale a dire, tra –128 e +127 byte di memoria rispetto all'indirizzo del PC corrente (contatore di programma). In caso di salto in avanti, l'indirizzo di destinazione può trovarsi entro uno spazio di 127 byte dal PC corrente. In caso di salto all'indietro, l'indirizzo di destinazione può trovarsi entro –128 byte dal PC corrente.
Calcolo dell'indirizzo di salto breve
Tutti i salti condizionali (JNC, JZ e DJNZ) sono salti brevi perché sono istruzioni a 2 byte. In queste istruzioni, il primo byte rappresenta il codice operativo e il secondo byte rappresenta l'indirizzo relativo. L'indirizzo di destinazione è sempre relativo al valore del contatore del programma. Per calcolare l'indirizzo di destinazione, il secondo byte viene aggiunto al PC dell'istruzione immediatamente sotto il salto. Dai un'occhiata al programma riportato di seguito -
Line PC Op-code Mnemonic Operand
1 0000 ORG 0000
2 0000 7800 MOV R0,#003
3 0002 7455 MOV A,#55H0
4 0004 6003 JZ NEXT
5 0006 08 INC R0
6 0007 04 AGAIN: INC A
7 0008 04 INC A
8 0009 2477 NEXT: ADD A, #77h
9 000B 5005 JNC OVER
10 000D E4 CLR A
11 000E F8 MOV R0, A
12 000F F9 MOV R1, A
13 0010 FA MOV R2, A
14 0011 FB MOV R3, A
15 0012 2B OVER: ADD A, R3
16 0013 50F2 JNC AGAIN
17 0015 80FE HERE: SJMP HERE
18 0017 END
Calcolo dell'indirizzo di destinazione del salto all'indietro
In caso di salto in avanti, il valore di spostamento è un numero positivo compreso tra 0 e 127 (da 00 a 7F in esadecimale). Tuttavia, per un salto all'indietro, lo spostamento è un valore negativo compreso tra 0 e –128.
Istruzioni CALL
CALL viene utilizzato per chiamare una subroutine o un metodo. Le subroutine vengono utilizzate per eseguire operazioni o attività che devono essere eseguite frequentemente. Ciò rende un programma più strutturato e consente di risparmiare spazio di memoria. Sono disponibili due istruzioni: LCALL e ACALL.
LCALL (lunga chiamata)
LCALL è un'istruzione a 3 byte in cui il primo byte rappresenta il codice operativo e il secondo e il terzo byte vengono utilizzati per fornire l'indirizzo della subroutine di destinazione. LCALL può essere utilizzato per chiamare subroutine disponibili nello spazio degli indirizzi di 64 KB dell'8051.
Per tornare al punto dopo l'esecuzione della subroutine richiamata, la CPU salva l'indirizzo dell'istruzione immediatamente sotto LCALL nello stack. Pertanto, quando viene chiamata una subroutine, il controllo viene trasferito a quella subroutine e il processore salva il PC (contatore del programma) sullo stack e inizia a prelevare le istruzioni dalla nuova posizione. L'istruzione RET (ritorno) trasferisce nuovamente il controllo al chiamante dopo aver terminato l'esecuzione della subroutine. Ogni subroutine utilizza RET come ultima istruzione.
ACALL (chiamata assoluta)
ACALL è un'istruzione a 2 byte, a differenza di LCALL che è di 3 byte. L'indirizzo di destinazione della subroutine deve essere compreso tra 2K byte poiché per l'indirizzo vengono utilizzati solo 11 bit dei 2 byte. La differenza tra ACALL e LCALL è che l'indirizzo di destinazione per LCALL può essere ovunque all'interno dello spazio degli indirizzi di 64 KB dell'8051, mentre l'indirizzo di destinazione di CALL è compreso in un intervallo di 2 KB.