- Comprendere l\'uso dei registri e delle istruzioni di confronto (CMP) in x86
- Implementare cicli e strutture logiche con salti condizionati
- Analizzare e tracciare il flusso di esecuzione di programmi assembly
- Utilizzare strumenti di simulazione per il test e il debugging
Il Flusso Condizionato e il Registro Flags
I salti condizionati si basano sul registro FLAGS della CPU, che registra lo stato dei confronti. Le istruzioni CMP confrontano due valori e impostano i flag Zero (ZF), Sign (SF), Overflow (OF), ecc.
La sintassi generale per utilizzare un salto condizionato è la seguente:
CMP <operando1>, <operando2> ; confronta i due valori e aggiorna i flag
<Jcc> <etichetta> ; salta all'etichetta se la condizione <cc> è vera
Dove:
- CMP = confronta i due operandi e imposta i flag nel registro di stato (ZF, SF, CF, OF...)
- <Jcc> = istruzione di salto condizionato (JE, JNE, JL, JG, ecc.)
- <etichetta> = nome simbolico della posizione di memoria a cui saltare
Tabella dei Salti Condizionati in Assembly x86
| Codice di esempio | Istruzione e descrizione |
|---|---|
|
CMP AX, 10 ; confronta AX con 10 JE uguale ; salta a 'uguale' se AX=10 |
JE – Jump if Equal (salta se uguale) |
|
CMP AX, 10 JNE diverso ; salta se ZF=0 (AX≠10) |
JNE – Jump if Not Equal (salta se diverso) |
|
CMP AX, 10 JG maggiore ; salta se AX > 10 (signed) |
JG – Jump if Greater (maggiore) |
|
CMP AX, 10 JL minore ; salta se AX < 10 (signed) |
JL – Jump if Less (minore) |
|
CMP AX, 10 JGE maggiore_o_uguale ; salta se AX >= 10 (signed) |
JGE – Jump if Greater or Equal (maggiore o uguale) |
|
CMP AX, 10 JLE minore_o_uguale ; salta se AX <= 10 (signed) |
JLE – Jump if Less or Equal (minore o uguale) |
Quando si utilizzano le istruzioni di salto condizionato in assembly x86, la CPU decide se saltare o meno in base allo stato di alcuni flag aggiornati dall’ultima istruzione di confronto o aritmetica, tipicamente l’istruzione CMP o SUB.
Ogni flag rappresenta una condizione particolare del risultato dell’operazione:
- ZF (Zero Flag): indica se il risultato è zero.
- SF (Sign Flag): indica se il risultato è negativo.
- CF (Carry Flag): indica un riporto/borrow.
- OF (Overflow Flag): indica un overflow in operazioni con segno.
Gli altri flag esistono per altre funzionalità della CPU (come parità, interrupt o direzione delle stringhe) e non influenzano direttamente i salti condizionati. Nella tabella qui sotto, i flag usati dai salti sono evidenziati, mentre quelli non rilevanti sono “oscurati” per facilitare la comprensione.
Questa tabella serve come riferimento per capire quali flag vengono verificati dalle diverse istruzioni di salto condizionato e come lo stato dei flag determina se il salto viene eseguito o meno.
| Flag | Descrizione |
|---|---|
| ZF (Zero Flag) | Indica se il risultato dell’ultima operazione è zero. ZF=1 se zero, ZF=0 altrimenti. Usato nei salti condizionati come JE, JNE |
| SF (Sign Flag) | Indica il segno del risultato. SF=1 se negativo, SF=0 se positivo. Usato nei salti condizionati come JL, JG |
| CF (Carry Flag) | Indica un riporto/borrow. CF=1 se c’è riporto, CF=0 altrimenti. Usato nei salti condizionati come JC, JNC |
| OF (Overflow Flag) | Indica overflow in operazioni con segno. OF=1 se overflow, OF=0 altrimenti. Usato nei salti condizionati come JO, JNO |
| PF (Parity Flag) | Indica se il numero di bit a 1 nel risultato è pari. Non usato nei salti condizionati. |
| AF (Auxiliary Carry Flag) | Riporto dal nibble basso al nibble alto. Non usato nei salti condizionati. |
| IF (Interrupt Flag) | Abilita/disabilita interrupt esterni. Non usato nei salti condizionati. |
| DF (Direction Flag) | Indica la direzione per le istruzioni di stringa. Non usato nei salti condizionati. |
Abbiamo visto quali sono i principali flag che influenzano il comportamento delle istruzioni di salto condizionato e come essi riflettano lo stato dell’ultima operazione aritmetica o di confronto.
Per comprendere appieno come funzionano i salti condizionati, è fondamentale osservare concretamente come i flag vengono impostati dopo un confronto e come questi valori determinano se il salto avviene o meno.
Nella tabella sottostante troverai esempi di codice assembly che includono un’istruzione CMP seguita da un salto condizionato. Per ogni esempio sono indicati i valori dei flag rilevanti al momento del salto e la condizione che risulta vera o falsa, mostrando quindi quando il salto viene eseguito o ignorato.
Questo esercizio ti aiuterà a consolidare la relazione tra il risultato di un confronto, i flag aggiornati dalla CPU e il comportamento delle istruzioni di salto condizionato, passando dalla teoria alla pratica.
In generale, nelle condizioni logiche e nei flag
- 1 indica che la condizione è vera,
- 0 indica che è falsa.
| Codice di esempio | Istruzione | Flag | Condizione |
|---|---|---|---|
MOV AX, 10 CMP AX, 10 ; AX = 10 confronto con 10 → ZF=1 JE uguale MOV BX, 0 ; ignorata se salto uguale: MOV BX, 1 |
JE | ZF=1, SF=0, CF=0, OF=0 | Vera |
MOV AX, 5 CMP AX, 10 ; AX=5 confronto con 10 → ZF=0 JE uguale MOV BX, 0 uguale: MOV BX, 1 |
JE | ZF=0, SF=1, CF=0, OF=0 | Falsa |
MOV AX, 5 CMP AX, 10 JNE diverso MOV BX, 0 diverso: MOV BX, 1 |
JNE | ZF=0, SF=1, CF=0, OF=0 | Vera |
MOV AX, 10 CMP AX, 10 JNE diverso MOV BX, 0 diverso: MOV BX, 1 |
JNE | ZF=1, SF=0, CF=0, OF=0 | Falsa |
Esercizio - Completa la tabella
| Codice di esempio | ZF | SF | CF | OF | Condizione |
|---|---|---|---|---|---|
|
MOV AX, 20 CMP AX, 15 ; confronto AX con 15 JL minore MOV BX, 0 minore: MOV BX, 1 |
|||||
|
MOV AX, 10 CMP AX, 10 ; confronto AX con 10 JGE maggiore_uguale MOV BX, 0 maggiore_uguale: MOV BX, 1 |
|||||
|
MOV AX, 5 CMP AX, 8 ; confronto AX con 8 JG maggiore MOV BX, 0 maggiore: MOV BX, 1 |
|||||
|
MOV AX, 12 CMP AX, 12 ; confronto AX con 12 JNE diverso MOV BX, 0 diverso: MOV BX, 1 |
- Completare la colonna "Flag" con i valori di ZF, SF, CF, OF al termine del confronto CMP.
- Indicare nella colonna "Condizione" se la condizione del salto (JL, JGE, JG, JNE) è Vera o Falsa in base ai valori dei flag e al confronto effettuato.