If, e tutte le altre istruzioni di controllo del flusso, sono implementato a livello logico come salti condizionali.
Quando si utilizza un'istruzione if, come questo:
int a = 1, b = 0
if (a > b)
{
...
Ovviamente, qualsiasi compilatore intelligente ottimizzare questo fuori. Se noi insegniamo specificamente il nostro compilatore di essere stupidi come possibile e generare istruzioni alla lettera, avremo qualcosa di simile al seguente fuori di esso:
my_if_statement:
CMP eax, ebx # intrinsically works by subtracting ebx from eax
# eax and ebx are not changed, but the arithmetic flags are
# if it was greater, jump to greater label
JG my_if_statement_was_true
# if it wasn't greater, we get here
my_if_statement_was_false:
# do something
# we're now done, so jump to the end of the statement
J my_if_statement_end
my_if_statement_was_true:
# do something else
# now we're done with the if statement
my_if_statement_end:
# program continues
Queste sono le istruzioni di montaggio, ognuno dei quali traducono (circa) direttamente al codici operativi del codice macchina. Il processore fa un mucchio di cose aggiuntive per supportare il processo di caricamento e recupero delle istruzioni, che è rilevante qui. C'è un registro speciale chiamato contatore del programma (indicato più avanti come registro PC), che tiene traccia della posizione del prossimo codice operativo che il processore sta per eseguire.
- Prima, l'istruzione CMP sottrae il secondo operando dal primo e scarta il risultato. Tuttavia, il registro FLAGS viene aggiornato con i risultati dell'operazione aritmetica.
- Quindi, l'istruzione JG controlla se è impostato il flag GREATER nel registro FLAGS. Dato che è nel nostro esempio (ricorda che 1> 0), esegue un salto.
- L'istruzione di salto modifica il contatore del programma (PC), che è il registro che controlla da dove la CPU leggerà l'istruzione successiva da.
- La CPU tenta quindi di leggere l'istruzione successiva. Da quando siamo saltati, l'istruzione successiva non è quella immediatamente successiva a quella precedentemente elaborata.
Questa è una panoramica del processo. Se vuoi una spiegazione più approfondita, ti consiglio di scrivere un semplice programma C con un'istruzione if, compilarlo, disassemblarlo (usando linux objdump
o un equivalente), e magari aggiungere un debugger ad esso ed eseguirlo.
linux objdump
manual
Per mostrare la prossima istruzione da eseguire in gdb
, utilizzare display/i $pc
Grande domanda! risposta complicata però. Hai bisogno di vedere che capita di capirlo completamente, ti consiglio di scrivere un semplice esempio, compilarlo, collegarlo ad un debugger e passarlo attraverso, un'istruzione alla volta. – Wug
@wug è un'ottima idea, grazie. – Nealon