Sök…


Oförutsedda hopp

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

Relativt nära hopp

jmp a_label är:

  • nära
    Den anger bara förskjutningsdelen av destinationens logiska adress . Segmentet antas vara CS .
  • relativ
    Instruktionen semantisk är jump rel bytes framåt 1 från nästa instruktionsadress eller IP = IP + rel .

Instruktionen är kodad som antingen EB <rel8> eller EB <rel16/32> , varvid monteraren tar upp den lämpligaste formen, föredrar vanligtvis en kortare.
Per montering av åsidosättande är möjlig, till exempel med NASM jmp SHORT a_label , jmp WORD a_label och jmp DWORD a_label genererar de tre möjliga formerna.

Absolut indirekt nära hopp

jmp bx och jmp WORD [aPointer] är:

  • nära
    De anger bara förskjutningsdelen av destinationens logiska adress. Segmentet antas vara CS .
  • absolut indirekt
    Instruktionens semantiska är att hoppa till adressen i reg eller mem eller IP = reg , IP = mem .

Instruktionen är kodad som FF /4 , för indirekt minne bestäms operandens storlek som för alla andra minnesåtkomst.

Absolut långa hopp

jmp 7c0h:0000h är:

  • långt
    Den anger båda delarna av den logiska adressen: segmentet och offset.

  • absolut Instruktionens semantiska är hopp till adresssegmentet: offset eller CS = segment, IP = offset .

Instruktionen är kodad som EA <imm32/48> beroende på kodstorlek.
Det är möjligt att välja mellan de två formerna i vissa monterare, till exempel med NASM jmp 7c0h: WORD 0000h och jmp 7c0h: DWORD 0000h genererar den första och den andra formen.

Absolut indirekta långa hopp

jmp FAR WORD [aFarPointer] är:

  • far Det specificerar båda delarna av den logiska adressen: segmentet och offset.

  • Absolut indirekt Instruktionens semantiska hoppar till segmentet: offset lagrat i mem 2 eller CS = mem[23:16/32], IP = [15/31:0] .

Instruktionen är kodad som FF /5 , storleken på operand kan styras med storleksspecifikationerna.
I NASM, lite inte intuitivt, är de jmp FAR WORD [aFarPointer] för en 16:16 operand och jmp FAR DWORD [aFarPointer] för en 16:32 operand.


Saknade hopp

  • nära absolut
    Kan emuleras med ett nära indirekt hopp.

      mov bx, target            ;BX = absolute address of target
      jmp bx
    
  • långt relativ
    Inte vettigt eller för smalt att använda ändå.


1 Två komplement används för att specificera en signerad offset och därmed hoppa bakåt.
2 Vilket kan vara en seg16: off16 eller en seg16: off32 , i storlekarna 16:16 och 16:32 .

Testförhållanden

För att använda ett villkorat hopp måste ett tillstånd testas. Att testa ett tillstånd här avser bara handlingen för att kontrollera flaggorna, den faktiska hoppningen beskrivs under Villkorade hopp .

x86 testar villkor genom att förlita sig på EFLAGS-registret, som innehåller en uppsättning flaggor som varje instruktion potentiellt kan ställa in.

Aritmetiska instruktioner, som sub eller add , och logiska instruktioner, som xor eller and , uppenbarligen "ställa in flaggorna". Detta innebär att flaggorna CF , OF , SF , ZF , AF , PF modifieras av dessa instruktioner. Alla instruktioner tillåts ändra flaggorna, till exempel cmpxchg modifierar ZF .

Kontrollera alltid instruktionsreferensen för att veta vilka flaggor som modifieras av en specifik instruktion.

x86 har en uppsättning villkorade hopp , som tidigare nämnts, som hoppar om och bara om vissa flaggor är inställda eller vissa är tydliga eller båda.


flaggor

Aritmetiska och logiska operationer är mycket användbara för att ställa in flaggorna. Till exempel efter en sub eax, ebx , för att nu inneha osignerade värden, har vi:

Flagga När inställd När det är klart
ZF När resultatet är noll.
EAX - EBX = 0 ⇒ EAX = EBX
När resultatet inte är noll.
EAX - EBX ≠ 0 ⇒ EAX ≠ EBX
CF När resultatet behövde bäras för MSb.
EAX - EBX <0 ⇒ EAX <EBX
När resultatet inte behövde bäras för MSb.
EAX - EBX ≮ 0 ⇒ EAX ≮ EBX
SF När resultat MSb är inställt. När resultat MSb inte är inställt.
AV När ett signerat överflöd inträffade. När ett signerat överflöde inte inträffade.
PF När antalet bitar som ställts in i minst betydande byte av resultat är jämnt. När antalet bitar som ställts in i minst signifikant byte av resultat är udda.
AF När den lägre BCD-siffran genererade en bär.
Det är bit 4 bär.
När den lägre BCD-siffran inte genererade en bär.
Det är bit 4 bär.

Icke-destruktiva tester

Den sub och and instruktioner ändra sin destination operand och skulle kräva två extra kopior (spara och återställa) för att hålla destination omodifierad.

För att utföra ett icke-destruktivt test finns instruktionerna cmp och test . De är identiska med deras destruktiva motsvarighet förutom att resultatet av operationen kastas, och endast flaggorna sparas .

Destruktiv Ej förstörande
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

Undertecknade och osignerade tester

CPU ger ingen speciell betydelse för att registrera värden 1 , tecken är en programmerare konstruktion. Det är ingen skillnad när du testar signerade och osignerade värden. Processorn beräknar tillräckligt med flaggor för att testa de vanliga aritmetiska förhållandena (lika, mindre än, större än, etc.) båda om operanderna skulle betraktas som signerade och osignerade.


1 Även om det har några instruktioner som är meningsfulla endast med specifika format, som två komplement. Detta är för att effektivisera koden eftersom implementering av algoritmen i programvara kräver mycket kod.

Villkorade hopp

Baserat på flaggernas tillstånd kan CPU antingen köra eller ignorera ett hopp. En instruktion som utför ett hopp baserat på flaggorna faller under det generiska namnet Jcc - Jump on Condition Code 1 .

Synonymer och terminologi

För att förbättra läsbarheten för monteringskoden definierade Intel flera synonymer för samma tillståndskod. Till exempel jae , jnb och jnc är alla samma tillståndskod CF = 0 .

Även om instruktionsnamnet kan ge ett mycket starkt tips om när du ska använda det eller inte, är det enda meningsfulla tillvägagångssättet att känna igen flaggorna som måste testas och sedan välja instruktionerna på lämpligt sätt.
Intel gav dock instruktionerna namn som är vettigt när de används efter en cmp instruktion. För denna diskussions cmp antas cmp att ha ställt flaggorna före ett villkorat hopp.

Jämlikhet

Operandarna är lika om ZF har ställts in, de skiljer sig annorlunda ut. För att testa för jämlikhet behöver vi 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)
Instruktion flaggor
je , jz ZF = 1
jne , jnz ZF = 0

Större än

För osignerade operander är destinationen större än källan om transporter inte behövdes, det vill säga om CF = 0 . När CF = 0 är det möjligt att operanderna var lika kommer testning av ZF att utvetydiga.

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)
Instruktion flaggor
jae , jnc , jnb CF = 0
ja , jnbe CF = 0, ZF = 0

För signerade operander måste vi kontrollera att SF = 0 , såvida det inte har skett ett signerat överflöde, i vilket fall den resulterande SF är omvänd. Eftersom OF = 0 om inget signerat överflöde inträffade och 1 annars, måste vi kontrollera att SF = OF .

ZF kan användas för att genomföra ett strikt / icke strikt test.

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)
Instruktion flaggor
jge , jnl SF = OF
jg , jnle SF = OF, ZF = 0

Mindre än

Dessa använder ovanstående omvända förhållanden.

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)
Instruktion flaggor
jbe , jna CF = 1 eller ZF = 1
jb , jc , jnae CF = 1
jle , jng SF! = OF eller ZF = 1
jl , jnge SF! = OF

Specifika flaggor

Varje flagga kan testas individuellt med j<flag_name> där flaggnamn inte innehåller släpet F (till exempel CFC , PFP ).

De återstående koderna som inte täckts tidigare är:

Instruktion Flagga
js SF = 1
jns SF = 0
jo OF = 1
jno OF = 0
jp , jpe (e = jämn) PF = 1
jnp , jpo (o = udda) PF = 0

Ytterligare ett villkorat hopp (extra ett)

Ett speciellt villkorat hopp med x86 testar inte flaggan. Istället testar det värdet för cx eller ecx register (baserat på det aktuella CPU-adressläget är 16 eller 32 bitar), och hoppet utförs när registret innehåller noll.

Denna instruktion var avsedd för validering av räknarregister ( cx/ecx ) framåt av rep -liknande instruktioner, eller före loop slingor.

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)
Instruktion Registrera (inte flagga)
jcxz , jecxz cx = 0 (16b-läge)
jcxz , jecxz ecx = 0 (32b-läge)

1 Eller något liknande.

Test aritmetiska relationer

Osignerade heltal

Större än

cmp eax, ebx
ja a_label  

Större än eller lika med

cmp eax, ebx
jae a_label  

Mindre än

cmp eax, ebx
jb a_label  

Mindre än eller lika

cmp eax, ebx
jbe a_label 

Likvärdig

cmp eax, ebx
je a_label 

Inte jämnlikt

cmp eax, ebx
jne a_label     

Signerade heltal

Större än

cmp eax, ebx
jg a_label  

Större än eller lika med

cmp eax, ebx
jge a_label  

Mindre än

cmp eax, ebx
jl a_label  

Mindre än eller lika

cmp eax, ebx
jle a_label 

Likvärdig

cmp eax, ebx
je a_label 

Inte jämnlikt

cmp eax, ebx
jne a_label 

a_label

I exemplen ovan är a_label för CPU när det testade tillståndet är "sant". När testat tillstånd är "falskt" fortsätter CPU: n vid nästa instruktion efter det villkorade hoppet.

synonymer

Det finns instruktionssynonymer som kan användas för att förbättra kodens läsbarhet.
Till exempel ja och jnbe (Hoppa icke under eller lika) är samma instruktion.

Signerade icke signerade följeslagarkoder

Drift Osignerad Signerad
> ja jg
> = jae jge
< jb jl
<= jbe jle
= je je
≠,! =, <> jne jne


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow