Salti e controllo del flusso
Da Hacknowledge.
L'Assembly non fornisce delle strutture per il controllo del flusso del codice versatili come i linguaggi ad alto livello (for, foreach, while, do while, switch...). Il controllo del flusso in un programma Assembly si fa nel modo più elementare possibile, nonché il primo inventato dagli informatici e oggi tanto deprecato nei linguaggi ad alto livello: i salti condizionati (equivalente al goto dei linguaggi ad alto livello se vogliamo). A basso livello fondamentalmente controllo la veridicità di una certa condizione esaminando il registro FLAG della CPU, e in caso affermativo salto ad una data etichetta nel codice. In questo modo posso sia creare degli if sia dei loop. Concettualmente, se voglio controllare che una variabile sia positiva ragionerò nel seguente modo:
confronta var,0 salta_se_maggiore etichetta_vero etichetta_falso: // Qui ci va il codice da eseguire se var<=0 etichetta_vero: // Qui ci va il codice da eseguire se var>0
Oppure ecco come è possibile fare l'equivalente di un ciclo for o while che, ad esempio, svolge una certa azione 10 volte:
poni var=0 loop: // Azioni da compiere incrementa var confronta var,10 salta_se_minore loop // Torno a loop finché var<10
// Qui metto il codice da eseguire una volta uscito dal loop
In Assembly tutto ciò è possibile attraverso due semplici tipi di istruzioni:
- cmp (compare) - Confronta due tipi di dati, e setta nel registro FLAG i flag giusti ricavati dal confronto (ad esempio Zero Flag se i due dati sono uguali, GF o LF se il secondo è rispettivamente maggiore o minore dell'altro ecc.)
- jmp (jump) - Serie di istruzioni per eseguire salti incondizionati o condizionati (in questo caso vengono esaminati gli opportuni valori nel registro FLAG).
Ecco i principali tipi di jump:
- jmp - Salto incondizionato. L'esecuzione del codice passa all'etichetta specificata senza controllare ulteriori condizioni. Esempio:
// Istruzioni jmp end // Il codice che c'è qui non verrà mai eseguito end: // L'esecuzione del codice arriva direttamente qui
- je/jz - jne/jnz - Salta se è uguale/se è zero - Salta se non è uguale/se non è zero. Le prime due istruzioni fanno esattamente la stessa cosa, ovvero saltano ad un'etichetta se lo Zero Flag è attivo. Lo Zero Flag può essere attivo se il confronto precedente ha dato zero, e ciò è possibile nel caso in cui i valori confrontati precedentemente sono risultati uguali. jne/jnz ovviamente sono le istruzioni duali, ovvero saltano ad una certa etichetta se lo Zero Flag non è settato.
// Istruzioni movl $1,%eax // Metto 1 in EAX cmpl $1,%eax // Confronto 1 e il valore in EAX je label // Salto se sono uguali a label ... label: // Istruzioni
- jg - jl - Rispettivamente saltano ad un'etichetta se dal confronto precedente il secondo valore è risultato maggiore o minore del primo.
- jge - jle - Rispettivamente saltano ad un'etichetta se dal confronto precedente il secondo valore è risultato maggiore o uguale o minore o uguale al primo.
Questi sono i salti principali che ci serviranno nei nostri esempi.

