Ricerca…


Salti incondizionati

jmp a_label                      ;Jump to a_label
jmp bx                           ;Jump to address in BX
jmp WORD [aPointer]              ;Jump to address in aPointer
jmp 7c0h:0000h                   ;Jump to segment 7c0h and offset 0000h
jmp FAR WORD [aFarPointer]       ;Jump to segment:offset in aFarPointer

Relativo vicino a salti

jmp a_label è:

  • vicino
    Specifica solo la parte offset dell'indirizzo logico di destinazione. Si presume che il segmento sia CS .
  • parente
    La semantica delle istruzioni è di salto rel byte 1 avanti dal prossimo indirizzo di istruzione o IP = IP + rel .

L'istruzione è codificata come EB <rel8> o EB <rel16/32> , l'assemblatore EB <rel16/32> il modulo più appropriato, di solito preferendo uno più corto.
Per l'override dell'assemblatore è possibile, ad esempio con NASM jmp SHORT a_label , jmp WORD a_label e jmp DWORD a_label generano le tre possibili forme.

Salto assoluto indiretto vicino

jmp bx e jmp WORD [aPointer] sono:

  • vicino
    Specificano solo la parte di offset dell'indirizzo logico di destinazione. Si presume che il segmento sia CS .
  • assoluto indiretto
    La semantica delle istruzioni è il salto all'indirizzo in reg o mem o IP = reg , IP = mem .

L'istruzione è codificata come FF /4 , per la memoria indiretta la dimensione dell'operando è determinata come per ogni altro accesso alla memoria.

Salti assoluti assoluti

jmp 7c0h:0000h è:

  • lontano
    Specifica entrambe le parti dell'indirizzo logico : il segmento e l'offset.

  • absolute La semantica dell'istruzione è il salto al segmento dell'indirizzo : offset o CS = segment, IP = offset .

L'istruzione è codificata come EA <imm32/48> seconda delle dimensioni del codice.
È possibile scegliere tra le due forme in alcuni assembler, ad esempio con NASM jmp 7c0h: WORD 0000h e jmp 7c0h: DWORD 0000h genera il primo e il secondo modulo.

Salti estremi indiretti assoluti

jmp FAR WORD [aFarPointer] è:

  • lontano Specifica entrambe le parti dell'indirizzo logico : il segmento e l'offset.

  • Assoluto indiretto La semantica dell'istruzione è il salto al segmento: offset memorizzato in mem 2 o CS = mem[23:16/32], IP = [15/31:0] .

L'istruzione è codificata come FF /5 , la dimensione dell'operando può essere il controller con gli identificatori di dimensione.
In NASM, un po 'non intuitivo, sono jmp FAR WORD [aFarPointer] per un operando 16:16 e jmp FAR DWORD [aFarPointer] per un operando 16:32 .


Salti mancanti

  • vicino assoluto
    Può essere emulato con un salto quasi indiretto.

      mov bx, target            ;BX = absolute address of target
      jmp bx
    
  • lontano parente
    In ogni caso, non ha senso o è troppo stretto.


1 Due complemento è usato per specificare un offset firmato e quindi saltare all'indietro.
2 Che può essere un seg16: off16 o un seg16: off32 , di dimensioni 16:16 e 16:32 .

Condizioni di prova

Per poter utilizzare un salto condizionale, è necessario testare una condizione. Il test di una condizione qui si riferisce solo all'atto di controllare le bandiere, il salto effettivo è descritto in Salti condizionali .

x86 verifica le condizioni facendo affidamento sul registro EFLAGS, che contiene una serie di flag che ogni istruzione può potenzialmente impostare.

Istruzioni aritmetiche, come sub o add , e le istruzioni logiche, come xor o and , ovviamente "impostare le bandiere". Ciò significa che i flag CF , OF , SF , ZF , AF , PF sono modificati da quelle istruzioni. Qualsiasi istruzione è autorizzata a modificare i flag, ad esempio, cmpxchg modifica lo ZF .

Controllare sempre il riferimento alle istruzioni per sapere quali bandiere sono state modificate da una specifica istruzione.

x86 ha una serie di salti condizionali , a cui si fa riferimento in precedenza, che salta se e solo se alcuni flag sono impostati o alcuni sono chiari o entrambi.


bandiere

Le operazioni aritmetiche e logiche sono molto utili nell'impostazione delle bandiere. Ad esempio, dopo un sub eax, ebx , per ora in possesso di valori senza segno , abbiamo:

Bandiera Quando impostato Quando è chiaro
ZF Quando il risultato è zero.
EAX - EBX = 0 ⇒ EAX = EBX
Quando il risultato non è zero.
EAX - EBX ≠ 0 ⇒ EAX ≠ EBX
CF Quando il risultato ha avuto bisogno di trasportare per il MSb.
EAX - EBX <0 ⇒ EAX <EBX
Quando il risultato non ha avuto bisogno di portare per il MSb.
EAX - EBX ≮ 0 ⇒ EAX ≮ EBX
SF Quando viene impostato il risultato MSb. Quando il risultato MSb non è impostato.
DI Quando si è verificato un overflow firmato. Quando non si verifica un overflow con segno.
PF Quando il numero di bit impostato nel byte di risultato meno significativo è pari. Quando il numero di bit impostato nel byte di risultato meno significativo è dispari.
AF Quando la cifra BCD inferiore ha generato un carry.
È il 4 ° carry.
Quando la cifra BCD inferiore non ha generato un carry.
È il 4 ° carry.

Test non distruttivi

Il sub e and istruzioni modificano la loro operando destinazione e richiederebbe due copie extra (salvataggio e ripristino) per mantenere la destinazione non modificato.

Per eseguire un test non distruttivo ci sono le istruzioni cmp e test . Sono identici alla loro controparte distruttiva, tranne che il risultato dell'operazione viene scartato e vengono salvate solo le bandiere .

Distruttivo Non distruttivo
sub cmp
and test

test eax, eax             ;and eax, eax
                          ;ZF = 1 iff EAX is zero

test eax, 03h             ;and eax, 03h
                          ;ZF = 1 if both bit[1:0] are clear
                          ;ZF = 0 if at least one of bit[1:0] is set

cmp eax, 241d             ;sub eax, 241d
                          ;ZF = 1 iff EAX is 241
                          ;CF = 1 iff EAX < 241

Prove firmate e non firmate

La CPU non dà alcun significato speciale per registrare i valori 1 , il segno è un costrutto programmatore. Non c'è alcuna differenza quando si testano i valori firmati e non firmati. Il processore calcola abbastanza flag per testare le solite relazioni aritmetiche (uguali, minori di, maggiori di, ecc.) Sia se gli operandi dovessero essere considerati firmati e non firmati.


1 Sebbene abbia alcune istruzioni che hanno senso solo con formati specifici, come il complemento a due. Questo per rendere il codice più efficiente poiché l'implementazione dell'algoritmo nel software richiederebbe molto codice.

Salti condizionati

In base allo stato dei flag, la CPU può eseguire o ignorare un salto. Un'istruzione che esegue un salto basato sui flag rientra nel nome generico di Jcc - Jump on Condition Code 1 .

Sinonimi e terminologia

Al fine di migliorare la leggibilità del codice assembly, Intel ha definito diversi sinonimi per lo stesso codice di condizione. Ad esempio, jae , jnb e jnc sono tutti lo stesso codice di condizione CF = 0 .

Mentre il nome dell'istruzione può dare un forte suggerimento su quando usarlo o meno, l'unico approccio significativo è riconoscere le bandiere che devono essere testate e quindi scegliere le istruzioni in modo appropriato.
Intel ha tuttavia fornito i nomi delle istruzioni che hanno perfettamente senso quando vengono utilizzati dopo un'istruzione cmp . Ai fini di questa discussione, si presume che cmp abbia impostato i flag prima di un salto condizionato.

Uguaglianza

L'operando è uguale se ZF è stato impostato, diversamente si differenziano. Per testare l'uguaglianza abbiamo bisogno di ZF = 1 .

je a_label           ;Jump if operands are equal
jz a_label           ;Jump if zero (Synonym)

jne a_label          ;Jump if operands are NOT equal
jnz a_label          ;Jump if not zero (Synonym)
istruzione bandiere
je , jz ZF = 1
jne , jnz ZF = 0

Più grande di

Per gli operandi senza segno , la destinazione è maggiore della sorgente se carry non era necessaria, ovvero CF = 0 . Quando CF = 0 è possibile che gli operandi fossero uguali, testando ZF si disambiguerebbe.

jae a_label      ;Jump if above or equal (>=)
jnc a_label      ;Jump if not carry (Synonym)
jnb a_label      ;Jump if not below (Synonym)

ja a_label       ;Jump if above  (>)
jnbe a_label     ;Jump if not below and not equal (Synonym)
istruzione bandiere
jae , jnc , jnb CF = 0
ja , jnbe CF = 0, ZF = 0

Per gli operandi firmati è necessario verificare che SF = 0 , a meno che non vi sia stato un overflow con segno, nel qual caso l' SF risultante viene invertito. Poiché OF = 0 se non si è verificato un overflow con segno e 1 in caso contrario, è necessario verificare che SF = OF .

ZF può essere utilizzato per implementare un test rigoroso / non rigoroso.

jge a_label      ;Jump if greater or equal (>=)
jnl a_label      ;Jump if not less (Synonym)

jg a_label       ;Jump if greater (>)
jnle a_label     ;Jump if not less and not equal (Synonym)
istruzione bandiere
jge , jnl SF = OF
jg , jnle SF = OF, ZF = 0

Meno di

Questi usano le condizioni invertite di sopra.

jbe a_label      ;Jump if below or equal (<=)
jna a_label      ;Jump if not above (Synonym)

jb a_label       ;Jump if below (<)
jc a_label       ;Jump if carry (Synonym)
jnae a_label     ;Jump if not above and not equal (Synonym)

;SIGNED 

jle a_label      ;Jump if less or equal (<=)
jng a_label      ;Jump if not greater (Synonym)

jl a_label       ;Jump if less (<)
jnge a_label     ;Jump if not greater and not equal (Synonym)
istruzione bandiere
jbe , jna CF = 1 o ZF = 1
jb , jc , jnae CF = 1
jle , jng SF! = OF o ZF = 1
jl , jnge SF! = OF

Bandiere specifiche

Ogni flag può essere testato individualmente con j<flag_name> dove flag_name non contiene il finale F (ad esempio CFC , PFP ).

I codici rimanenti non trattati in precedenza sono:

istruzione Bandiera
js SF = 1
jns SF = 0
jo OF = 1
jno OF = 0
jp , jpe (e = even) PF = 1
jnp , jpo (o = dispari) PF = 0

Un altro salto condizionale (uno extra)

Un salto condizionale x86 speciale non verifica il flag. Invece esegue il test del valore del registro cx o ecx (in base alla modalità corrente dell'indirizzo della CPU 16 o 32 bit) e il salto viene eseguito quando il registro contiene zero.

Questa istruzione è stata progettata per la convalida del registro contatore ( cx/ecx ) prima delle istruzioni simili a rep o prima dei loop loop.

jcxz  a_label   ; jump if cx (16b mode) or ecx (32b mode) is zero
jecxz a_label   ; synonym of jcxz (recommended in source code for 32b target)
istruzione Registrati (non flag)
jcxz , jecxz cx = 0 (modalità 16b)
jcxz , jecxz ecx = 0 (modalità 32b)

1 O qualcosa del genere.

Testare le relazioni aritmetiche

Numeri interi senza segno

Più grande di

cmp eax, ebx
ja a_label  

Maggiore o uguale

cmp eax, ebx
jae a_label  

Meno di

cmp eax, ebx
jb a_label  

Meno o uguale

cmp eax, ebx
jbe a_label 

Pari

cmp eax, ebx
je a_label 

Non uguale

cmp eax, ebx
jne a_label     

Interi firmati

Più grande di

cmp eax, ebx
jg a_label  

Maggiore o uguale

cmp eax, ebx
jge a_label  

Meno di

cmp eax, ebx
jl a_label  

Meno o uguale

cmp eax, ebx
jle a_label 

Pari

cmp eax, ebx
je a_label 

Non uguale

cmp eax, ebx
jne a_label 

a_label

Negli esempi sopra la a_label è la destinazione target per la CPU quando la condizione testata è "vera". Quando la condizione testata è "false", la CPU continuerà con l'istruzione successiva successiva al salto condizionato.

Sinonimi

Esistono sinonimi di istruzioni che possono essere utilizzati per migliorare la leggibilità del codice.
Ad esempio ja e jnbe (salto non inferiore o uguale) sono la stessa istruzione.

Codici companion non firmati firmati

operazione unsigned firmato
> ja jg
> = jae jge
< jb jl
<= jbe jle
= je je
≠,! =, <> jne jne


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow