Zoeken…


Onvoorwaardelijke sprongen

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

Relatief in de buurt van sprongen

jmp a_label is:

  • in de buurt
    Het specificeert alleen het offset-gedeelte van het logische adres van bestemming. Het segment wordt verondersteld CS .
  • familielid
    De semantische instructie is jump rel bytes vooruit 1 vanaf het volgende instructieadres of IP = IP + rel .

De instructie is gecodeerd als EB <rel8> of EB <rel16/32> , waarbij de assembler de meest geschikte vorm EB <rel16/32> , meestal de voorkeur aan een kortere.
Per assembler is overschrijven mogelijk, bijvoorbeeld met NASM jmp SHORT a_label , jmp WORD a_label en jmp DWORD a_label genereren de drie mogelijke formulieren.

Absoluut indirect in de buurt van sprongen

jmp bx en jmp WORD [aPointer] zijn:

  • in de buurt
    Ze specificeren alleen het offset-gedeelte van het logische adres van bestemming. Het segment wordt verondersteld CS .
  • absoluut indirect
    De semantiek van de instructies is springen naar het adres in reg of mem of IP = reg , IP = mem .

De instructie is gecodeerd als FF /4 , voor indirect geheugen wordt de grootte van de operand bepaald zoals voor elke andere geheugentoegang.

Absoluut ver springt

jmp 7c0h:0000h is:

  • ver
    Het specificeert beide delen van het logische adres: het segment en de offset.

  • absoluut De semantiek van de instructie is springen naar het adressegment: offset of CS = segment, IP = offset .

De instructie is gecodeerd als EA <imm32/48> afhankelijk van de EA <imm32/48> .
Het is mogelijk om te kiezen tussen de twee vormen in sommige assembler, bijvoorbeeld met NASM jmp 7c0h: WORD 0000h en jmp 7c0h: DWORD 0000h genereert de eerste en tweede vorm.

Absoluut indirect verre sprongen

jmp FAR WORD [aFarPointer] is:

  • ver Het specificeert beide delen van het logische adres: het segment en de offset.

  • Absoluut indirect De semantiek van de instructie is springen naar het segment: offset opgeslagen in mem 2 of CS = mem[23:16/32], IP = [15/31:0] .

De instructie is gecodeerd als FF /5 , de grootte van de operand kan een controller zijn met de maataanduidingen.
In NASM, een beetje niet intuïtief, zijn ze jmp FAR WORD [aFarPointer] voor een 16:16 operand en jmp FAR DWORD [aFarPointer] voor een 16:32 operand.


Ontbrekende sprongen

  • bijna absoluut
    Kan worden nagebootst met een bijna indirecte sprong.

      mov bx, target            ;BX = absolute address of target
      jmp bx
    
  • ver familielid
    Sowieso niet logisch of te beperkt.


1 Twee complement wordt gebruikt om een ondertekende offset te specificeren en dus achteruit te springen.
2 Dat kan een seg16 zijn: off16 of een seg16: off32 , in de maten 16:16 en 16:32 .

Testomstandigheden

Om een voorwaardelijke sprong te gebruiken, moet een voorwaarde worden getest. Het testen van een voorwaarde verwijst hier alleen naar het controleren van de vlaggen, het daadwerkelijke springen wordt beschreven onder Voorwaardelijke sprongen .

x86 test voorwaarden door te vertrouwen op het EFLAGS-register, dat een set vlaggen bevat die elke instructie mogelijk kan instellen.

Rekenkundige instructies, zoals sub of add , en logische instructies, zoals xor of and , uiteraard "stel de vlaggen in". Dit betekent dat de vlaggen CF , OF , SF , ZF , AF , PF door die instructies zijn gewijzigd. Elke instructie is toegestaan om de vlaggen te wijzigen, bijvoorbeeld, cmpxchg wijzigt de ZF .

Controleer altijd de instructiereferentie om te weten welke vlaggen door een specifieke instructie zijn gewijzigd.

x86 heeft een reeks voorwaardelijke sprongen , waarnaar eerder wordt verwezen, die springen als en alleen als sommige vlaggen zijn ingesteld of sommige duidelijk zijn of beide.


vlaggen

Rekenkundige en logische bewerkingen zijn erg handig bij het instellen van de vlaggen. Bijvoorbeeld, na een sub eax, ebx , die nu niet-ondertekende waarden bevat, hebben we:

Vlag Wanneer ingesteld Wanneer duidelijk
ZF Wanneer het resultaat nul is.
EAX - EBX = 0 ⇒ EAX = EBX
Wanneer het resultaat niet nul is.
EAX - EBX ≠ 0 ⇒ EAX ≠ EBX
CF Wanneer het resultaat nodig was voor de MSb.
EAX - EBX <0 ⇒ EAX <EBX
Wanneer het resultaat niet nodig was voor de MSb.
EAX - EBX ≮ 0 ⇒ EAX ≮ EBX
SF Wanneer resultaat MSb is ingesteld. Wanneer resultaat MSb niet is ingesteld.
VAN Wanneer een ondertekende overloop plaatsvond. Wanneer een ondertekende overloop niet heeft plaatsgevonden.
PF Als het aantal bits dat is ingesteld als minst significante byte van het resultaat even is. Als het aantal bits dat is ingesteld als minst significante byte van het resultaat oneven is.
AF Toen het lagere BCD-cijfer een carry genereerde.
Het is bit 4 carry.
Wanneer de onderste BCD cijfer heeft een carry genereren.
Het is bit 4 carry.

Niet-destructieve tests

De sub en and instructies wijzigen hun bestemmingsoperand en vereisen twee extra exemplaren (opslaan en herstellen) om de bestemming ongewijzigd te houden.

Om een niet-destructieve test uit te voeren, zijn er de instructies cmp en test . Ze zijn identiek aan hun destructieve tegenhanger, behalve dat het resultaat van de operatie wordt verwijderd en alleen de vlaggen worden opgeslagen .

vernietigend Niet destructief
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

Ondertekende en niet-ondertekende tests

De CPU geeft geen speciale betekenis aan het registreren van waarden 1 , teken is een programmeurconstructie. Er is geen verschil bij het testen van ondertekende en niet-ondertekende waarden. De processor berekent voldoende vlaggen om de gebruikelijke rekenkundige relaties (gelijk, kleiner dan, groter dan, enz.) Te testen, beide als de operanden als ondertekend en niet-ondertekend moeten worden beschouwd.


1 Hoewel het enkele instructies heeft die alleen zinvol zijn met specifieke formaten, zoals het complement van twee. Dit is om de code efficiënter te maken, omdat het implementeren van het algoritme in software veel code zou vereisen.

Voorwaardelijke sprongen

Op basis van de status van de vlaggen kan de CPU een sprong uitvoeren of negeren. Een instructie die een sprong uitvoert op basis van de vlaggen, valt onder de generieke naam Jcc - Jump on Condition Code 1 .

Synoniemen en terminologie

Om de leesbaarheid van de assemblagecode te verbeteren, heeft Intel verschillende synoniemen voor dezelfde staatscode gedefinieerd. jae , jnb en jnc zijn bijvoorbeeld allemaal dezelfde voorwaardecode CF = 0 .

Hoewel de naam van de instructie een zeer sterke hint kan geven over wanneer deze moet worden gebruikt of niet, is de enige zinvolle benadering om de vlaggen te herkennen die moeten worden getest en vervolgens de juiste instructies te kiezen.
Intel gaf echter de instructies namen die volkomen logisch zijn wanneer ze worden gebruikt na een cmp instructie. Voor de toepassing van deze discussie, cmp zal worden uitgegaan van de vlaggen te hebben ingesteld voordat een voorwaardelijke sprong.

Gelijkheid

De operand is gelijk als ZF is ingesteld, ze verschillen anders. Om gelijkheid te testen hebben we ZF = 1 nodig .

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)
Instructie vlaggen
je , jz ZF = 1
jne , jnz ZF = 0

Groter dan

Voor niet-ondertekende operanden is de bestemming groter dan de bron als carry niet nodig was, dat wil zeggen, als CF = 0 . Wanneer CF = 0 is het mogelijk dat de operanden gelijk waren, het testen van ZF zal ondubbelzinnig zijn.

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

Voor ondertekende operanden moeten we controleren of SF = 0 , tenzij er een ondertekende overloop is geweest, in welk geval de resulterende SF wordt omgekeerd. Omdat OF = 0 als er geen ondertekende overloop heeft plaatsgevonden en anders 1, moeten we controleren of SF = OF .

ZF kan worden gebruikt om een strikte / niet-strikte test uit te voeren.

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

Minder dan

Deze gebruiken de omgekeerde voorwaarden van hierboven.

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

Specifieke vlaggen

Elke vlag kan afzonderlijk worden getest met j<flag_name> waarbij vlagnaam niet de volgende F bevat (bijvoorbeeld CFC , PFP ).

De resterende codes die niet eerder zijn behandeld, zijn:

Instructie Vlag
js SF = 1
jns SF = 0
jo OF = 1
jno OF = 0
jp , jpe (e = even) PF = 1
jnp , jpo (o = oneven) PF = 0

Nog een voorwaardelijke sprong (extra)

Een speciale x86 voorwaardelijke sprong test de vlag niet. In plaats daarvan test het de waarde van cx of ecx register (gebaseerd op de huidige CPU-adresmodus die 16 of 32 bit is), en wordt de sprong uitgevoerd wanneer het register nul bevat.

Deze gebruiksaanwijzing is bestemd voor de validatie van teller register ( cx/ecx ) vooruit rep -achtige instructies of vooruit loop loops.

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)
Instructie Registreren (geen vlag)
jcxz , jecxz cx = 0 (16b-modus)
jcxz , jecxz ecx = 0 (32b-modus)

1 Of zoiets.

Test rekenkundige relaties

Niet-ondertekende gehele getallen

Groter dan

cmp eax, ebx
ja a_label  

Groter dan of gelijk aan

cmp eax, ebx
jae a_label  

Minder dan

cmp eax, ebx
jb a_label  

Minder dan of gelijk

cmp eax, ebx
jbe a_label 

Gelijk

cmp eax, ebx
je a_label 

Niet gelijk

cmp eax, ebx
jne a_label     

Getekende gehele getallen

Groter dan

cmp eax, ebx
jg a_label  

Groter dan of gelijk aan

cmp eax, ebx
jge a_label  

Minder dan

cmp eax, ebx
jl a_label  

Minder dan of gelijk

cmp eax, ebx
jle a_label 

Gelijk

cmp eax, ebx
je a_label 

Niet gelijk

cmp eax, ebx
jne a_label 

a_label

In bovenstaande voorbeelden is het a_label doelbestemming voor CPU wanneer de geteste voorwaarde "waar" is. Wanneer de geteste voorwaarde "onwaar" is, gaat de CPU verder met de volgende instructie na de voorwaardelijke sprong.

Synoniemen

Er zijn instructiesynoniemen die kunnen worden gebruikt om de leesbaarheid van de code te verbeteren.
ja en jnbe (Springen niet lager of gelijk) zijn bijvoorbeeld dezelfde instructie.

Ondertekende niet-ondertekende begeleidende codes

Operatie ongetekend Getekend
> ja jg
> = jae jge
< jb jl
<= jbe jle
= je je
≠,! =, <> jne jne


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow