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.