Sei sulla pagina 1di 10

Istruzioni di salto incondizionato con Esempi in

Assembly
8086 Tipi di Istruzioni di salto (o ramificazione)
1

Esistono due tipi di ramificazioni o salti vale a dire rami condizionali e incondizionati.

Istruzioni di salto incondizionato

I salti incondizionati sono quelli in cui il contatore del programma salta all'indirizzo dell'etichetta
fornito all'interno dell'istruzione. Ad esempio: JMP NEXT (essendo NEXT l’etichetta)

Istruzioni di salto condizionato

I salti condizionati sono quelle istruzioni la cui esecuzione si basa sul verificarsi di qualche
condizione. Controlla una o più condizioni dei flag e trasferisce il controllo dell’esecuzione del
programma in una nuova posizione di memoria, quella dell’etichetta. Ci sono due tipi di salti:
Lontani e Vicini (Far and Near). Nei salti lontani, il contatore del programma salta alla posizione
della memoria che si trova al di fuori del segmento di codice corrente, mentre nei salti vicini, l'IP
punta all'indirizzo di memoria all'interno del segmento di codice corrente ed è per questo che il
registro CS rimane invariato nei salti vicini. La sintassi di queste istruzioni è:

Opcode LABEL la LABEL nel sorgente e` seguita da “:”

Si tratta di un'istruzione a 2 byte costituita da Opcode a 1 byte ed etichetta a 1 byte. Il valore


dell'etichetta è compreso tra 00 e FF. È esteso con segno a 16 bit e aggiunto al contenuto del
registro IP. L'indirizzo di destinazione deve essere all'interno dell’intervallo da -128 a +127 byte
di IP. Le condizioni dei flag vengono controllate a seconda dell'istruzione opcode, se sono vere il
controllo del programma viene trasferito all'indirizzo di memoria puntato dal registro IP mentre
se le condizioni sono false il programma continua in modo sequenziale.

Lista delle Istruzioni di salto condizionato

La tabella seguente mostra i mnemonici (opcode) di tutte le istruzioni sui salti condizionali.

Testing
Instructions Operation
Condition
JA/JNBE Jump if Above/Not Below or Equal (DIVERSO DA) C=0 and Z=0
Jump if Above or Equal/ Jump if Not Below/Jump if No Carry
JAE/JNB/JNC C=0
(DIVERSO e NESSUN RIPORTO)
JB/JNAE Jump if Below/ Jump if Not Above or Equal (<) C=1
JBE/JNA Jump if Below or Equal/ Jump if Not Above (<=) (C or Z) =1
JC Jump if Carry C=1
JNC Jump if Not Carry C=0 2
JCXZ Jump if the CX register=0 CX=0
JE/JZ Jump if Equal/Jump if Zero (=)* Z=1
((S xor O) or
JG/JNLE Jump if Greater/Jump if Not Less Than or Equal
Z) = 0
JGE/JNL Jump if Greater or Equal/Jump if Not Less Than (S xor O)=0
JL/JNGE Jump if Less Than/Jump if Not Greater Than or Equal (S xor O)=1
((S xor O) or
JLE/JNG Jump if Less than or Equal/Jump if Not Greater
Z) = 1
JNE/JNZ Jump if Not Equal/ Jump if Not Zero Z=0
JNP/JPO Jump if Not Parity/Jump if Parity Odd (DISPARI) P=0
JNS Jump if Not Signed/Jump if Positive (POSITIVO) S=0
JO Jump if Overflow O=1
JNO Jump if Not Overflow O=0
JP/JPE Jump if Parity/ Jump if Parity Even (PARI) P=1
JS Jump if Signed/ Jump if Negative (NEGATIVO) S=1

Queste istruzioni vengono eseguite dopo alcune altre istruzioni di operazioni aritmetico-logiche
che influiscono sul contenuto dei registri dei FLAG. NOTA BENE: tutte le istruzioni con
maggiore o minore (JA, JAE,JB, JBE,JE, JG, JGE, JLE,JL e i loro negati) devono essere
precedute da CMP. Vediamo queste istruzioni in dettaglio attraverso esempi.

Esempio di Confronto in Assembly


Il codice seguente confronta due numeri e stampa a video se il primo numero è uguale, maggiore
o minore del secondo numero. Questo codice viene implementato utilizzando tre rami
condizionali che sono JE, JB e JA.

Il codice assembly

L'istruzione Compare (CMP) in CMP AH,CH sottrae il contenuto di CH da AH e setta i flag ZF,
CF e SF secondo il risultato e la tabella sotto
CF ZF SF

AH=CH 0 1 0

AH>CH 0 0 0

AH<CH 1 0 1 3

L'istruzione JE controlla ZF, se il flag zero (ZF) sarà uguale a 1 il contatore del programma passa
a L1 che stamperà il messaggio "Numeri Uguali" sullo schermo dell'emulatore. Se il flag zero ZF
è 0, il contatore del programma salterà all'istruzione successiva che è JB L2.

L’istruzione JB controlla se il flag CF è 1. Se è 1, il controllo viene trasferito all'indirizzo


dell'etichetta L2, che stamperà il messaggio "Numero 1 < Numero 2" sullo schermo
dell'emulatore.

JA controllerà i flag CF e ZF. Se entrambi sono 0, l'IP salterà all'indirizzo di destinazione L3,
che stamperà il messaggio "Numero 1 > Numero 2" sullo schermo dell'emulatore. Inoltre, se sia
CF che ZF sono uguali a 1 o se uno di essi è 0 e l'altro è 1, il programma continuerà a essere
eseguito in sequenza.

ORG 100h
.MODEL SMALL
.DATA
NUM_1 DB 23H
NUM_2 DB 93H
MSG DB " Numeri uguali$"
MSG1 DB "Numero 1 < Numero 2$"
MSG2 DB "Numero > Numero 2$"

.CODE
MOV AX, @DATA
MOV DS, AX

MOV AH,NUM_1
MOV CH,NUM_2
CMP AH,CH
JE L1 ; AH = CH
JB L2 ; AH < CH
JA L3 ; AH > CH
ret

L1: ;si notino i : dopo la label


MOV DX,OFFSET MSG
MOV AH,09H
INT 21H
RET

L2:
MOV DX,OFFSET MSG1
MOV AH,09H
INT 21H
RET

L3:
MOV DX,OFFSET MSG2
MOV AH,09H
INT 21H
RET
4

Esempio di controllo del Flag di Carry


Le istruzioni JAE/JNB/JNC controllano il flag di carry (CF). Se è 0, passa all'etichetta
destinazione. Ad esempio:
ADD AH, BH
JAE L1

Supponiamo AH=C9H e BH=7AH. La prima istruzione aggiunge C9 e 7AH e dà 143. Si genera


carry, quindi, CF = 1. Ora, dopo l'esecuzione dell'istruzione JAE, il contatore del programma non
salterà a L1, ma eseguirà l'istruzione successiva a JAE. A meno che non si usi JC invece.

Sostituire ora l'istruzione ADD con l'istruzione CMP. Se AH è maggiore o uguale al dato in BH,
il contatore del programma salterà all'etichetta L1.

Esempio
assembly e
output
ORG 100h
.MODEL SMALL
.DATA
VAR_1 DB 0C9H
VAR_2 DB 7AH
.CODE
MOV AH,VAR_1
MOV BH,VAR_2
ADD AH,BH
JAE L1
ADD AH,BH
RET
L1:ADD BH,AH
RET

JO Esempio Assembly
Il codice seguente mostra il comportamento dell'istruzione JO. Somma due numeri e controlla
l'overflow. Se il risultato è troppo grande per essere adatto al registro di destinazione, il bit di
overflow viene impostato su 1. L'istruzione JO controlla il flag di overflow. Se è 1, il controllo
verrà trasferito all'etichetta NEXT che mostrerà quindi il messaggio di "OVERFLOW" sullo
schermo dell'emulatore. Se Of=0, la somma viene memorizzata nel REGISTRO BL.

In questo esempio, i due numeri sono 0C9H e 95H. La loro somma dà 15E con conseguente 5
overflow. Siccome OF = 1, dopo l'istruzione JO, vengono eseguite le istruzioni dopo l'etichetta
NEXT. Provare anche con NUM_1=0A6h e NUM_2=60h che non da` overflow.

Assembly Code
ORG 100h
.MODEL SMALL
.DATA
MSG DB "OVERFLOW$"
NUM_1 DB 0C9H
NUM_2 DB 95H
Output
.CODE
MOV AX, @DATA
MOV DS, AX

MOV AH,NUM_1
MOV CH,NUM_2
ADD AH,CH
JO NEXT
MOV BL,AH
RET

NEXT:
MOV DX,OFFSET MSG
MOV AH,09H
INT 21H
RET

L'istruzione JNO è opposta all'istruzione JO. Quando OF è 0, l'istruzione JNO farà saltare il
contatore del programma all'istruzione il cui indirizzo di etichetta è fornito all'interno
dell'istruzione JNO.

JNP Esempio Assembly


L'istruzione JNP controlla il flag di parità. Se la parità è dispari (PF=0), il contatore del
programma salterà all'indirizzo dell'etichetta. L'istruzione JP controlla se la parità è pari (PF=1).

Codice assembly

Questo esempio di assembly controlla la parità e la visualizza nello schermo dell'emulatore.


ORG 100h
.MODEL SMALL
.DATA
MSG DB "EVEN PARITY$"
MSG1 DB "ODD PARITY$"
NUM_1 DB 0C9H
NUM_2 DB 95H
RESULT DB 01 DUP(?) 6
.CODE

MOV AX, @DATA


MOV DS, AX Output
MOV AH,NUM_1
MOV CH,NUM_2
ADD AH,CH
JP NEXT
MOV DX,OFFSET MSG1
MOV AH,09H
INT 21H
RET

NEXT:
MOV DX,OFFSET MSG
MOV AH,09H
INT 21H
RET

JNS Esempio Assembly


C'è un'altra istruzione che viene utilizzata per verificare se il risultato è positivo o negativo e
salta all'indirizzo dell'etichetta a seconda del segno del risultato. L'istruzione JNS (Jump Not
Signed) salta se il risultato dell'istruzione precedente positivo, mentre l'istruzione JS è un salto se
il risultato dell'istruzione precedente e` negativo.

Codice assembly

Il codice nell'esempio somma due numeri e verifica se il risultato è un numero positivo o meno.
Se il numero è positivo, il programma smette di funzionare altrimenti il programma salterà
all'etichetta NEXT in cui il risultato viene moltiplicato con -1 per convertirlo in un numero
positivo.
ORG 100h
.MODEL SMALL
.DATA
NUM_1 DW -3C9H
NUM_2 DW 95H
.CODE
MOV AX,@DATA
MOV DS, AX
MOV AX,NUM_1 7
MOV CX,NUM_2
ADD AX,CX
JS NEXT
RET

NEXT:
MOV BX,-1H ;moltiplichiamo il risultato per -1 per cambiarne il segno
MUL BX
RET

Output

Qualora si usasse BL il prodotto viene fatto su BX per AX e si ottiene un risultato diverso che non
coincide col valore positivo di AX; si osservi l’immagine sotto
8

LOOP
E` un’istruzione di tipo NEAR, esegue in automatico le seguenti 2 istruzioni:

dec CX
jnz label
che quindi non appaiono, il registro CX va settato al valore corrispondente al numero di cicli da
eseguire.

Il programma sotto assomiglia ad un do… while esegue per 3 volte la somma ax+10h fino a che
non si azzera cx
Qualora la condizione nel DO….WHILE si voglia diversa bisogna usare uno schema diverso,
come il seguente, dove si somma fino ad F0:
xor ax, ax

somma:
add ax, 10h 9

cmp ax,F0h
jne somma

IL CICLO WHILE, CONTROLLO IN TESTA


While (condizione) Label:

{Istruzioni} Cmp AX, valore

Jnb(jnl) fine

Istruzioni

(Loop) jump label


Il ciclo while controlla ad inizio ciclo, si puo` usare
fine: ret
Jnb o jnl che sono equivalenti, per il ritorno si puo`

Usare jmp ma anche loop. Nell’esempio sotto si


esegue la somma continua e si usa loop con cx inizializzato ad un valore non nullo.

Se al posto di loop usiamo jmp cx non viene usato e qualsiasi valore iniziale abbia resta immutato.
10

Qui alla fine si potrebbe modificare con: sub dx,cx avendo prima copiato il val iniziale di cx in dx
Il ciclo FOR
Come il ciclo while usa il controllo ad inizio ciclo. Il programma che esegue la somma continua
col ciclo for usa un contatore noi abbiamo scelto un indice SI

Potrebbero piacerti anche