In Assembly 8086, i salti condizionati sono istruzioni che consentono di eseguire un salto a un’altra posizione del programma solo se una determinata condizione viene soddisfatta. Le condizioni sono basate sullo stato dei flag del processore, che vengono impostati in base alle istruzioni precedenti.
Flag del processore
I flag del processore sono dei registri speciali che mantengono lo stato di alcune condizioni, come ad esempio il risultato di un’operazione aritmetica o la presenza di un overflow. Ecco una breve lista dei flag del processore più comuni:
- CF (Carry Flag): viene impostato quando si verifica un carry o un borrow in un’operazione aritmetica.
- PF (Parity Flag): indica se il numero di bit a 1 nel risultato di un’operazione è pari o dispari.
- AF (Auxiliary Flag): viene impostato quando si verifica un carry o un borrow nei primi 4 bit di un’operazione aritmetica.
- ZF (Zero Flag): viene impostato quando il risultato di un’operazione è zero.
- SF (Sign Flag): indica il segno del risultato di un’operazione, dove 0 indica un risultato positivo e 1 indica un risultato negativo.
- OF (Overflow Flag): viene impostato quando si verifica un overflow in un’operazione aritmetica.
Istruzioni di salto
Le istruzioni di salto condizionato sono precedute da un’istruzione che imposta i flag del processore in base a una determinata condizione. Ecco alcune delle istruzioni di salto condizionato più comuni:
- JE (Jump if Equal): salta se ZF=1 (il risultato dell’operazione precedente è zero).
- JNE (Jump if Not Equal): salta se ZF=0 (il risultato dell’operazione precedente non è zero).
- JA (Jump if Above): salta se CF=0 e ZF=0 (il risultato dell’operazione precedente è maggiore di zero).
- JAE (Jump if Above or Equal): salta se CF=0 (il risultato dell’operazione precedente è maggiore o uguale a zero).
- JB (Jump if Below): salta se CF=1 (il risultato dell’operazione precedente è negativo).
- JBE (Jump if Below or Equal): salta se CF=1 o ZF=1 (il risultato dell’operazione precedente è negativo o zero).
- JL (Jump if Less): salta se SF≠OF (il risultato dell’operazione precedente è negativo).
- JLE (Jump if Less or Equal): salta se SF≠OF o ZF=1 (il risultato dell’operazione precedente è negativo o zero).
- JG (Jump if Greater): salta se ZF=0 e SF=OF (il risultato dell’operazione precedente è maggiore di zero).
- JGE (Jump if Greater or Equal): salta se SF=OF (il risultato dell’operazione precedente è maggiore o uguale a zero).
ESEMPI: SALTI CONDIZIONATI ASSEMBLY 8086
MOV AX, 5 ; carica il valore 5 in AX
MOV BX, 3 ; carica il valore 3 in BX
ADD AX, BX ; somma AX e BX
JL negative ; salta a negative se il risultato è negativo
MOV CX, 10 ; altrimenti carica il valore 10 in CX
JMP end ; salta alla fine del programma
negative:
MOV CX, -10 ; carica il valore -10 in CX
end:
; il programma continua qui
In questo esempio, le istruzioni MOV e ADD vengono utilizzate per caricare i registri AX e BX con i valori 5 e 3, rispettivamente, e per sommarli insieme. Successivamente, l’istruzione JL salta alla label negative solo se il risultato dell’operazione ADD è negativo. Se il risultato non è negativo, il programma salta direttamente alla label end utilizzando l’istruzione JMP. A seconda del risultato dell’operazione ADD, il registro CX viene caricato con il valore 10 o -10.
Salti condizionati Assembly 8086: calcolo del valore assoluto di un numero
MOV AX, -5 ; carica il valore -5 in AX
CMP AX, 0 ; confronta AX con 0
JGE end ; salta alla fine del programma se AX è maggiore o uguale a 0
NEG AX ; altrimenti, nega il valore di AX
end:
; il programma continua qui
In questo esempio, l’istruzione MOV viene utilizzata per caricare il registro AX con il valore -5. Successivamente, l’istruzione CMP viene utilizzata per confrontare il valore di AX con 0. Se il valore di AX è maggiore o uguale a 0, il programma salta direttamente alla label end utilizzando l’istruzione JGE, perché il valore di AX è già un valore assoluto. Altrimenti, il programma nega il valore di AX utilizzando l’istruzione NEG e poi salta alla label end.
Salti condizionati Assembly 8086: Confronto di 2 stringhe
MOV SI, offset str1 ; carica l'indirizzo della prima stringa in SI
MOV DI, offset str2 ; carica l'indirizzo della seconda stringa in DI
compare_loop:
MOV AL, [SI] ; carica un carattere dalla prima stringa in AL
MOV BL, [DI] ; carica un carattere dalla seconda stringa in BL
CMP AL, BL ; confronta i caratteri
JE continue ; salta a continue se i caratteri sono uguali
JL less_than ; salta a less_than se il carattere della prima stringa è minore di quello della seconda
JG greater_than ; salta a greater_than se il carattere della prima stringa è maggiore di quello della seconda
continue:
INC SI ; incrementa l'indice della prima stringa
INC DI ; incrementa l'indice della seconda stringa
CMP AL, 0 ; confronta il carattere di fine stringa con 0
JNE compare_loop ; ripete il ciclo se il carattere di fine stringa non è stato raggiunto
JMP end ; salta alla fine del programma
less_than:
MOV CX, -1 ; carica il valore -1 in CX
JMP end ; salta alla fine del programma
greater_than:
MOV CX, 1 ; carica il valore 1 in CX
JMP end ; salta alla fine del programma
end:
; il programma continua qui
In questo esempio, l’indirizzo delle due stringhe viene caricato nei registri SI e DI utilizzando l’istruzione MOV. Successivamente, viene avviato un ciclo di confronto tra i caratteri delle due stringhe utilizzando un’istruzione di salto condizionato differente in base alla relazione tra i caratteri correnti delle due stringhe: JE se i caratteri sono uguali, JL se il carattere della prima stringa è minore di quello della seconda, e JG se il carattere della prima stringa è maggiore di quello della seconda.
Se i caratteri sono uguali, il programma salta alla label continue utilizzando l’istruzione JE. Se il carattere della prima stringa è minore di quello della seconda, il programma salta alla label less_than utilizzando l’istruzione JL. Al contrario, se il carattere della prima stringa è maggiore di quello della seconda, il programma salta alla label greater_than utilizzando l’istruzione JG.
Dopo ogni confronto, il programma incrementa l’indice della prima e della seconda stringa utilizzando l’istruzione INC e verifica se è stato raggiunto il carattere di fine stringa utilizzando l’istruzione CMP. Se il carattere di fine stringa non è stato raggiunto, il ciclo continua con un’altra iterazione utilizzando l’istruzione JNE per saltare alla label compare_loop. Quando il carattere di fine stringa è stato raggiunto, il programma salta alla label end utilizzando l’istruzione JMP.
Se il carattere della prima stringa è minore di quello della seconda, il programma carica il valore -1 nel registro CX utilizzando l’istruzione MOV e salta alla label end utilizzando l’istruzione JMP. Al contrario, se il carattere della prima stringa è maggiore di quello della seconda, il programma carica il valore 1 nel registro CX utilizzando l’istruzione MOV e salta alla label end utilizzando l’istruzione JMP.
Infine, il programma continua a eseguire le istruzioni dopo la label end.