Passa al contenuto principale

Istruzioni processore x86

Le seguenti tabelle sono per riferimento rapido: sono utili per la programmazione pratica, ma omettono molteplici dettagli che serve sapere, e che trovate nel resto del materiale.

Si ricorda che utilizziamo la sintassi GAS/AT&T, dove le istruzioni sono nel formato opcode source destination. Nella colonna notazione, indicheremo con [bwl] le istruzioni che richiedono la specifica delle dimensioni. Quando la dimensione è deducibile dai registri utilizzati, questi suffissi si possono omettere.

Per gli operandi, useremo le seguenti sigle:

  • r per un registro (come in mov %eax, %ebx);
  • m per un indirizzo di memoria;
  • i per un valore immediato (come in mov $0, %eax).

Per gli indirizzi in memoria, abbiamo a disposizione tre notazioni:

  • immediato, come in mov numero, %eax;
  • tramite registro, come in mov (%esi), %eax;
  • con indice, come in mov matrice(%esi, %ecx, 4).

Si ricorda che non tutte le combinazioni sono permesse nell'architettura x86: nessuna istruzione generale supporta l'indicazione di entrambi gli operandi in memoria (cioè, non si può scrivere movl x, y o mov (%eax), (%ebx)). Fanno eccezione le istruzioni stringa come la movs, usando operandi impliciti.

Spostamento di dati

IstruzioneNome estesoNotazioneComportamento
movMovemov[bwl] r/m/i, r/mScrive il valore sorgente nel destinatario. Non modifica alcun flag.
leaLoad Effective Addresslea m, rScrive l'indirizzo m nel registro destinatario.
xchgExchangexchg[bwl] r/m, r/mScambia il valore del sorgente con quello del destinatario.
cbwConvert Byte to WordcbwEstende il contenuto di %al su %ax, interpretandone il contenuto come intero.
cwdeConvert Word to DoublewordcwdeEstende il contenuto di %ax su %eax, interpretandone il contenuto come intero.
pushPush onto the Stackpush[wl] r/m/iAggiunge il valore sorgente in cima allo stack (destinatario implicito).
popPop from the Stackpop[wl] r/mRimuove un valore dallo stack (sorgente implicito) lo scrive nel destinatario.

Aritmetica

IstruzioneNome estesoNotazioneComportamento
addAdditionadd[bwl] r/m/i, r/mSomma sorgente e destinatario, scrive il risultato sul destinatario. Valido sia per naturali che interi. Aggiorna SF, ZF, CF e OF.
subSubtractionsub[bwl] r/m/i, r/mSottrae il sorgente dal destinatario, scrive il risultato sul destinatario. Valido sia per naturali che interi. Aggiorna SF, ZF, CF e OF.
adcAddition with Carryadc[bwl] r/m/i, r/mSomma sorgente, destinatario e CF, scrive il risultato sul destinatario. Valido sia per naturali che interi. Aggiorna SF, ZF, CF e OF.
sbbSubtraction with Borrowsub[bwl] r/m/i, r/mSottrae il sorgente e CF dal destinatario, scrive il risultato sul destinatario. Valido sia per naturali che interi. Aggiorna SF, ZF, CF e OF.
incIncrementinc[bwl] r/mSomma 1 (sorgente implicito) al destinatario. Aggiorna SF, ZF, e OF, ma non CF.
decDecrementdec[bwl] r/mSottrae 1 (sorgente implicito) al destinatario. Aggiorna SF, ZF, e OF, ma non CF.
negNegationneg[bwl] r/mSostituisce il destinatario con il suo opposto. Aggiorna ZF, SF e OF. Modifica CF.

Le seguenti istruzioni hanno operandi e destinatari impliciti, che variano in base alla dimensione dell'operazione. Usano in oltre composizioni di più registri: useremo %dx_%ax per indicare un valore i cui bit più significativi sono scritti in %dx e quelli meno significativi in %ax.

IstruzioneNome estesoNotazioneComportamento
mulUnsigned Multiply, 8 bitmulb r/mCalcola su 16 bit il prodotto tra naturali del sorgente e %al, scrive il risultato su %ax. Se il risultato non è riducibile a 8 bit, mette CF e OF a 1, altrimenti a 0.
mulUnsigned Multiply, 16 bitmulw r/mCalcola su 32 bit il prodotto tra naturali del sorgente e %ax, scrive il risultato su %dx_%ax. Se il risultato non è riducibile a 16 bit, mette CF e OF a 1, altrimenti a 0.
mulUnsigned Multiply, 32 bitmull r/mCalcola su 64 bit il prodotto tra naturali del sorgente e %eax, scrive il risultato su %edx_%eax. Se il risultato non è riducibile a 32 bit, mette CF e OF a 1, altrimenti a 0.
imulSigned Multiply, 8 bitimulb r/mCalcola su 16 bit il prodotto tra interi del sorgente e %al, scrive il risultato su %ax. Se il risultato non è riducibile a 8 bit, mette CF e OF a 1, altrimenti a 0.
imulSigned Multiply, 16 bitimulw r/mCalcola su 32 bit il prodotto tra interi del sorgente e %ax, scrive il risultato su %dx_%ax. Se il risultato non è riducibile a 16 bit, mette CF e OF a 1, altrimenti a 0.
imulSigned Multiply, 32 bitimull r/mCalcola su 64 bit il prodotto tra interi del sorgente e %eax, scrive il risultato su %edx_%eax. Se il risultato non è riducibile a 32 bit, mette CF e OF a 1, altrimenti a 0.
IstruzioneNome estesoNotazioneComportamento
divUnsigned Divide, 8 bitdivb r/mCalcola su 8 bit la divisione tra naturali tra %ax (dividendo implicito) e il sorgento (divisore). Scrive il quoziente su %al e il resto su %ah. Se il quoziente non è rappresentabile su 8 bit, causa crash del programma.
divUnsigned Divide, 16 bitdivw r/mCalcola su 16 bit la divisione tra naturali tra %dx_%ax (dividendo implicito) e il sorgento (divisore). Scrive il quoziente su %ax e il resto su %dx. Se il quoziente non è rappresentabile su 16 bit, causa crash del programma.
divUnsigned Divide, 32 bitdivl r/mCalcola su 32 bit la divisione tra naturali tra %edx_%eax (dividendo implicito) e il sorgento (divisore). Scrive il quoziente su %eax e il resto su %edx. Se il quoziente non è rappresentabile su 32 bit, causa crash del programma.
idivSigned Divide, 8 bitidivb r/mCalcola su 8 bit la divisione tra interi tra %ax (dividendo implicito) e il sorgento (divisore). Scrive il quoziente su %al e il resto su %ah. Se il quoziente non è rappresentabile su 8 bit, causa crash del programma.
idivSigned Divide, 16 bitidivw r/mCalcola su 16 bit la divisione tra interi tra %dx_%ax (dividendo implicito) e il sorgento (divisore). Scrive il quoziente su %ax e il resto su %dx. Se il quoziente non è rappresentabile su 16 bit, causa crash del programma.
idivSigned Divide, 32 bitidivl r/mCalcola su 32 bit la divisione tra interi tra %edx_%eax (dividendo implicito) e il sorgento (divisore). Scrive il quoziente su %eax e il resto su %edx. Se il quoziente non è rappresentabile su 32 bit, causa crash del programma.

Logica binaria

Le seguenti istruzioni operano bit a bit: data per esempio la and, l'i-esimo bit del risultato è l'and logico tra gli i-esimi bit di sorgente e destinatario.

IstruzioneNotazioneComportamento
notnot[bwl] r/mSostituisce il destinatario con la sua negazione.
andand r/m/i, r/mCalcola l'and logico tra sorgente e destinatario, scrive il risultato sul destinatario.
oror r/m/i, r/mCalcola l'or logico tra sorgente e destinatario, scrive il risultato sul destinatario.
xorxor r/m/i, r/mCalcola lo xor logico tra sorgente e destinatario, scrive il risultato sul destinatario.

Traslazione e Rotazione

IstruzioneNome estesoNotazioneComportamento
shlShift Logical Leftshl[bwl] i/r r/mSia nn l'operando sorgente, esegue lo shift a sinistra del destinatario nn volte, impostando a 0 gli nn bit meno significativi. In ciascuno shift, il bit più significativo viene lasciato in CF. Come registro sorgente si può utilizzare solo %cl. Il sorgente può essere omesso, in quel caso n=1n=1.
salShift Arithmetic Leftsal[bwl] i/r r/mSia nn l'operando sorgente, esegue lo shift a sinistra del destinatario nn volte, impostando a 0 gli nn bit meno significativi. In ciascuno shift, il bit più significativo viene lasciato in CF. Se il bit più significativo ha cambiato valore almeno una volta, imposta OF a 1. Come registro sorgente si può utilizzare solo %cl. Il sorgente può essere omesso, in quel caso n=1n=1.
shrShift Logical Rightshr[bwl] i/r r/mSia nn l'operando sorgente, esegue lo shift a destra del destinatario nn volte, impostando a 0 gli nn bit più significativi. In ciascuno shift, il bit meno significativo viene lasciato in CF. Come registro sorgente si può utilizzare solo %cl. Il sorgente può essere omesso, in quel caso n=1n=1.
sarShift Arithmetic Rightsar[bwl] i/r r/mSia nn l'operando sorgente e ss il valore del bit più significativo del destinatario, esegue lo shift a destra del destinatario nn volte, impostando a ss gli nn bit più significativi. In ciascuno shift, il bit meno significativo viene lasciato in CF. Come registro sorgente si può utilizzare solo %cl. Il sorgente può essere omesso, in quel caso n=1n=1.
rolRotate Leftrol[bwl] i/r r/mSia nn l'operando sorgente, esegue la rotazione a sinistra del destinatario nn volte. In ciascuna rotazione, il bit più significativo viene sia lasciato in CF sia ricopiato al posto del bit meno significativo. Come registro sorgente si può utilizzare solo %cl. Il sorgente può essere omesso, in quel caso n=1n=1.
rorRotate Rightror[bwl] i/r r/mSia nn l'operando sorgente, esegue la rotazione a destra del destinatario nn volte. In ciascuna rotazione, il bit meno significativo viene sia lasciato in CF sia ricopiato al posto del bit più significativo. Come registro sorgente si può utilizzare solo %cl. Il sorgente può essere omesso, in quel caso n=1n=1.
rclRotate with Carry Leftrcl[bwl] i/r r/mSia nn l'operando sorgente, esegue la rotazione con carry a sinistra del destinatario nn volte. In ciascuna rotazione, il bit più significativo viene lasciato in CF, mentre il valore di CF viene ricopiato al posto del bit meno significativo. Come registro sorgente si può utilizzare solo %cl. Il sorgente può essere omesso, in quel caso n=1n=1.
rcrRotate with Carry Rightrcr[bwl] i/r r/mSia nn l'operando sorgente, esegue la rotazione con carry a destra del destinatario nn volte. In ciascuna rotazione, il bit meno significativo viene lasciato in CF, mentre il valore di CF viene ricopiato al posto del bit più significativo. Come registro sorgente si può utilizzare solo %cl. Il sorgente può essere omesso, in quel caso n=1n=1.

Controllo di flusso

IstruzioneNome estesoNotazioneComportamento
jmpUnconditional Jumpjmp m/rSalta incondizionatamente all'indirizzo specificato.
callCall Procedurecall m/rChiamata a procedura all'indirizzo specificato. Salva l'indirizzo della prossima istruzione nello stack, così che il flusso corrente possa essere ripreso con una ret.
retReturn from ProcedureretRitorna ad un flusso di esecuzione precedente, rimuovendo dallo stack l'indirizzo precedentemente salvato da una call.

La tabella seguente elenca i salti condizionati. I salti condizionati usano i flag per determinare se la condizione di salto è vera. Per un uso sempre coerente, assicurarsi che l'istruzione di salto segua immediatamente una cmp, o altre istruzioni che non hanno modificano i flag dopo la cmp. Dati gli operandi della cmp ed una condizione c, per esempio c = "maggiore o uguale", la condizione è vera se destinatario c sorgente. Nella tabella che segue, quando ci si riferisce ad un confronto fra sorgente e destinatario si intendono gli operandi della cmp precedente.

IstruzioneNome estesoNotazioneComportamento
cmpCompare Two Operandscmp[bwl] r/m/i, r/mConfronta i due operandi e aggiorna i flag di conseguenza.
jeJump if Equalje mSalta se destinatario == sorgente.
jneJump if Not Equaljne mSalta se destinatario != sorgente.
jaJump if Aboveja mSalta se, interpretandoli come naturali, destinatario > sorgente.
jaeJump if Above or Equaljae mSalta se, interpretandoli come naturali, destinatario >= sorgente.
jbJump if Belowjb mSalta se, interpretandoli come naturali, destinatario < sorgente.
jbeJump if Below or Equaljbe mSalta se, interpretandoli come naturali, destinatario <= sorgente.
jgJump if Greaterjg mSalta se, interpretandoli come interi, destinatario > sorgente.
jgeJump if Greater or Equaljge mSalta se, interpretandoli come interi, destinatario >= sorgente.
jlJump if Lessjl mSalta se, interpretandoli come interi, destinatario < sorgente.
jleJump if Less or Equaljle mSalta se, interpretandoli come interi, destinatario <= sorgente.
jzJump if Zerojz mSalta se ZF è 1.
jnzJump if Not Zerojnz mSalta se ZF è 0.
jcJump if Carryjc mSalta se CF è 1.
jncJump if Not Carryjnc mSalta se CF è 0.
joJump if Overflowjo mSalta se OF è 1.
jnoJump if Not Overflowjno mSalta se OF è 0.
jsJump if Signjs mSalta se SF è 1.
jnsJump if Not Signjns mSalta se SF è 0.

Operazioni condizionali

Per alcune operazioni tipiche, sono disponibili istruzioni specifiche il cui comportamento dipende dai flag e, quindi, dal risultato di una precedente cmp. Anche qui, quando ci si riferisce ad un confronto fra sorgente e destinatario si intendono gli operandi della cmp precedente.

La famiglia di istruzioni loop supporta i cicli condizionati più tipici. Rimangono d'interesse didattico come istruzioni specializzate ma, curiosamente, nei processori moderni sono generalmente meno performanti degli equivalenti che usino dec,cmp e salti condizionati.

IstruzioneNome estesoNotazioneComportamento
loopUnconditional Looploop mDecrementa %ecx e salta se il risultato è (ancora) diverso da 0.
loopeLoop if Equalloope mDecrementa %ecx e salta se entrambe le condizioni sono vere: 1)%ecx è (ancora) diverso da 0, 2) destinatario == sorgente.
loopneLoop if Not Equalloopne mDecrementa %ecx e salta se entrambe le condizioni sono vere: 1)%ecx è (ancora) diverso da 0, 2) destinatario != sorgente.
loopzLoop if Zeroloopz mDecrementa %ecx e salta se entrambe le condizioni sono vere: 1)%ecx è (ancora) diverso da 0, 2) ZF è 1.
loopnzLoop if Not Zeroloopnz mDecrementa %ecx e salta se entrambe le condizioni sono vere: 1)%ecx è (ancora) diverso da 0, 2) ZF è 0.

La famiglia di istruzioni set permette di salvare il valore di un confronto in un registro o locazione di memoria. Tale operando può essere solo da 1 byte.

IstruzioneNome estesoNotazioneComportamento
seteSet if Equalsete r/mImposta l'operando a 1 se destinatario == sorgente, a 0 altrimenti.
setneSet if Not Equalsetne r/mImposta l'operando a 1 se destinatario != sorgente, a 0 altrimenti.
setaSet if Aboveseta r/mImposta l'operando a 1 se, interpretandoli come naturali, destinatario > sorgente, a 0 altrimenti.
setaeSet if Above or Equalsetae r/mImposta l'operando a 1 se, interpretandoli come naturali, destinatario >= sorgente, a 0 altrimenti.
setbSet if Belowsetb r/mImposta l'operando a 1 se, interpretandoli come naturali, destinatario < sorgente, a 0 altrimenti.
setbeSet if Below or Equalsetbe r/mImposta l'operando a 1 se, interpretandoli come naturali, destinatario <= sorgente, a 0 altrimenti.
setgSet if Greatersetg r/mImposta l'operando a 1 se, interpretandoli come interi, destinatario > sorgente, a 0 altrimenti.
setgeSet if Greater or Equalsetge r/mImposta l'operando a 1 se, interpretandoli come interi, destinatario >= sorgente, a 0 altrimenti.
setlSet if Lesssetl r/mImposta l'operando a 1 se, interpretandoli come interi, destinatario < sorgente, a 0 altrimenti.
setleSet if Less or Equalsetle r/mImposta l'operando a 1 se, interpretandoli come interi, destinatario <= sorgente, a 0 altrimenti.
setzSet if Zerosetz r/mImposta l'operando a 1 se ZF è 1, a 0 altrimenti.
setnzSet if Not Zerosetnz r/mImposta l'operando a 1 se ZF è 0, a 0 altrimenti.
setcSet if Carrysetc r/mImposta l'operando a 1 se CF è 1, a 0 altrimenti.
setncSet if Not Carrysetnc r/mImposta l'operando a 1 se CF è 0, a 0 altrimenti.
setoSet if Overflowseto r/mImposta l'operando a 1 se OF è 1, a 0 altrimenti.
setnoSet if Not Overflowsetno r/mImposta l'operando a 1 se OF è 0, a 0 altrimenti.
setsSet if Signsets r/mImposta l'operando a 1 se SF è 1, a 0 altrimenti.
setnsSet if Not Signsetns r/mImposta l'operando a 1 se SF è 0, a 0 altrimenti.

La famiglia di istruzioni cmov permette di eseguire, solo se il confronto ha avuto successo, una mov da memoria a registro o da registro a registro. Gli operandi possono essere solo a 2 o 4 byte, non 1.

IstruzioneNome estesoNotazioneComportamento
cmoveMove if Equalcmove[wl] r/m rEsegue la mov se destinatario == sorgente, altrimenti non fa nulla.
cmovneMove if Not Equalcmovne[wl] r/m rEsegue la mov se destinatario != sorgente, altrimenti non fa nulla.
cmovaMove if Abovecmova[wl] r/m rEsegue la mov se, interpretandoli come naturali, destinatario > sorgente, altrimenti non fa nulla.
cmovaeMove if Above or Equalcmovae[wl] r/m rEsegue la mov se, interpretandoli come naturali, destinatario >= sorgente, altrimenti non fa nulla.
cmovbMove if Belowcmovb[wl] r/m rEsegue la mov se, interpretandoli come naturali, destinatario < sorgente, altrimenti non fa nulla.
cmovbeMove if Below or Equalcmovbe[wl] r/m rEsegue la mov se, interpretandoli come naturali, destinatario <= sorgente, altrimenti non fa nulla.
cmovgMove if Greatercmovg[wl] r/m rEsegue la mov se, interpretandoli come interi, destinatario > sorgente, altrimenti non fa nulla.
cmovgeMove if Greater or Equalcmovge[wl] r/m rEsegue la mov se, interpretandoli come interi, destinatario >= sorgente, altrimenti non fa nulla.
cmovlMove if Lesscmovl[wl] r/m rEsegue la mov se, interpretandoli come interi, destinatario < sorgente, altrimenti non fa nulla.
cmovleMove if Less or Equalcmovle[wl] r/m rEsegue la mov se, interpretandoli come interi, destinatario <= sorgente, altrimenti non fa nulla.
cmovzMove if Zerocmovz[wl] r/m rEsegue la mov se ZF è 1, altrimenti non fa nulla.
cmovnzMove if Not Zerocmovnz[wl] r/m rEsegue la mov se ZF è 0, altrimenti non fa nulla.
cmovcMove if Carrycmovc[wl] r/m rEsegue la mov se CF è 1, altrimenti non fa nulla.
cmovncMove if Not Carrycmovnc[wl] r/m rEsegue la mov se CF è 0, altrimenti non fa nulla.
cmovoMove if Overflowcmovo[wl] r/m rEsegue la mov se OF è 1, altrimenti non fa nulla.
cmovnoMove if Not Overflowcmovno[wl] r/m rEsegue la mov se OF è 0, altrimenti non fa nulla.
cmovsMove if Signcmovs[wl] r/m rEsegue la mov se SF è 1, altrimenti non fa nulla.
cmovnsMove if Not Signcmovns[wl] r/m rEsegue la mov se SF è 0, altrimenti non fa nulla.

Istruzioni stringa

Le istruzioni stringa sono ottimizzate per eseguire operazioni tipiche su vettori in memoria. Hanno esclusivamente operandi impliciti, che rende la specifica delle dimensioni non opzionale.

IstruzioneNome estesoNotazioneComportamento
cldClear Direction FlagcldImposta DF a 0, implicando che le istruzioni stringa procederanno per indirizzi crescenti.
stdSet Direction FlagstdImposta DF a 1, implicando che le istruzioni stringa procederanno per indirizzi decrescenti.
lodsLoad Stringlods[bwl]Legge 1/2/4 byte all'indirizzo in %esi e lo scrive in %al/%ax/%eax. Se DF è 0, incrementa %esi di 1/2/4, se è 1 lo decrementa.
stosStore Stringstos[bwl]Legge il valore in %al/%ax/%eax e lo scrive nei 1/2/4 byte all'indirizzo in %edi. Se DF è 0, incrementa %edi di 1/2/4, se è 1 lo decrementa.
movsMove String to Stringmovs[bwl]Legge 1/2/4 byte all'indirizzo in %esi e lo scrive nei 1/2/4 byte all'indirizzo in %edi. Se DF è 0, incrementa %edi di 1/2/4, se è 1 lo decrementa.
cmpsCompare Stringscmps[bwl]Confronta gli 1/2/4 byte all'indirizzo in %esi (sorgente) con quelli all'indirizzo in %edi (destinatario). Aggiorna i flag così come fa cmp.
scasScan Stringscas[bwl]Confronta %al/%ax/%eax (sorgente) con gli 1/2/4 byte all'indirizzo in %edi (destinatario). Aggiorna i flag così come fa cmp.

Repeat Instruction

Le istruzioni stringa possono essere ripetute senza controllo di programma, usando il prefisso rep.

IstruzioneNome estesoNotazioneComportamento
repUnconditional Repeat Instructionrep [opcode]Dato n il valore in %ecx, ripete l'operazione opcode n volte, decrementando %ecx fino a 0. Compatibile con lods, stos, movs.
repeRepeat Instruction if Equalrepe [opcode]Dato n il valore in %ecx, decrementa %ecx e ripete l'operazione opcode finché 1) %ecx è (ancora) diverso da 0, e 2) gli operandi di questa ripetizione erano uguali. Compatibile con cmps e scas.
repneRepeat Instruction if Not Equalrepne [opcode]Dato n il valore in %ecx, decrementa %ecx e ripete l'operazione opcode finché 1) %ecx è (ancora) diverso da 0, e 2) gli operandi di questa ripetizione erano disuguali. Compatibile con cmps e scas.

Altre istruzioni

IstruzioneNome estesoNotazioneComportamento
nopNo OperationnopNon cambia lo stato del processore in alcun modo, eccetto per il registro %eip.

Le seguenti istruzioni sono di interesse didattico ma non per le esercitazioni, in quanto richiedono privilegi di esecuzione.

IstruzioneNome estesoNotazioneComportamento
inInput from Portin r/i rLegge da una porta di input ad un registro.
outOutput to Portout r r/iScrive da un registro ad una porta di output.
insInput String from Portins[bwl]Legge 1/2/4 byte dalla porta di input indicata in %dx e li scrive nei 1/2/4 byte all'indirizzo in %edi.
outsOutput String to Portouts[bwl]Legge 1/2/4 byte all'indirizzo indicato da %esi e li scrive alla porta di output indicata in %dx.
hltHalthltBlocca ogni operazione del processore.