Suche…


Bedingungslose Sprünge

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

Relative Nahsprünge

jmp a_label ist:

  • nahe
    Es gibt nur den Offset-Teil der logischen Adresse des Ziels an. Das Segment wird als CS .
  • relativ
    Die Anweisungssemantik springt rel Bytes vorwärts von der nächsten Anweisungsadresse 1 oder IP = IP + rel .

Der Befehl wird entweder als EB <rel8> oder EB <rel16/32> , wobei der Assembler die am besten geeignete Form EB <rel16/32> , wobei er normalerweise eine kürzere Form bevorzugt.
Pro Assembler-Überschreibung ist möglich, zum Beispiel mit NASM jmp SHORT a_label , jmp WORD a_label und jmp DWORD a_label generieren die drei möglichen Formulare.

Absolute indirekte Nahsprünge

jmp bx und jmp WORD [aPointer] sind:

  • nahe
    Sie geben nur den Offset-Teil der logischen Adresse des Ziels an. Das Segment wird als CS .
  • absolut indirekt
    Die Semantik der Anweisungen ist an die Adresse in reg oder mem oder IP = reg , IP = mem springen.

Die Anweisung ist als FF /4 codiert, für indirekte Speicher wird die Größe des Operanden wie für jeden anderen Speicherzugriff bestimmt.

Absolute Weitsprünge

jmp 7c0h:0000h ist:

  • weit
    Sie gibt beide Teile der logischen Adresse an: das Segment und den Offset.

  • absolut Die Semantik der Anweisung springt in das Adresssegment : Offset oder CS = segment, IP = offset .

Die Anweisung wird abhängig von der Codegröße als EA <imm32/48> codiert.
Es ist möglich, in einem Assembler zwischen den beiden Formularen zu wählen, beispielsweise mit NASM jmp 7c0h: WORD 0000h und jmp 7c0h: DWORD 0000h erzeugen das erste und das zweite Formular.

Absolute indirekte Weitsprünge

jmp FAR WORD [aFarPointer] ist:

  • far Gibt beide Teile der logischen Adresse an: das Segment und den Offset.

  • Absolut indirekt Die Semantik des Befehls springt in das Segment: Offset, gespeichert in Mem 2 oder CS = mem[23:16/32], IP = [15/31:0] .

Die Anweisung ist als FF /5 codiert, die Größe des Operanden kann mit den Größenangaben gesteuert werden.
In NASM, ein bisschen nicht intuitiv, sind sie jmp FAR WORD [aFarPointer] für einen 16.16 - Operanden und jmp FAR DWORD [aFarPointer] für einen 16.32 Operanden.


Fehlende Sprünge

  • fast absolut
    Kann mit einem nahezu indirekten Sprung emuliert werden.

      mov bx, target            ;BX = absolute address of target
      jmp bx
    
  • weit relativ
    Machen Sie sowieso keinen Sinn oder zu engen Gebrauch.


1 Zwei Komplemente werden verwendet, um einen vorzeichenbehafteten Versatz anzugeben und somit rückwärts zu springen.
2 Welches kann ein seg16: off16 oder ein seg16: off32 der Größen 16:16 und 16:32 sein .

Testbedingungen

Um einen bedingten Sprung zu verwenden, muss eine Bedingung getestet werden. Das Testen einer Bedingung bezieht sich hier nur auf das Prüfen der Flags. Das tatsächliche Springen wird unter Bedingte Sprünge beschrieben .

x86 testet Bedingungen, indem er sich auf das EFLAGS-Register stützt, das eine Reihe von Flags enthält, die jeder Befehl möglicherweise setzen kann.

Arithmetische Anweisungen wie sub oder add und logische Anweisungen wie xor oder and "setzen die Flags". Dies bedeutet, dass die Flags CF , OF , SF , ZF , AF , PF durch diese Anweisungen modifiziert werden. Jede Anweisung darf die Flags jedoch ändern, zum Beispiel ändert cmpxchg den ZF .

Überprüfen Sie immer die Anweisungsreferenz, um zu wissen, welche Flags von einer bestimmten Anweisung geändert werden.

x86 hat eine Reihe von bedingten Sprüngen , auf die zuvor Bezug genommen wurde, die nur dann springen, wenn einige Flags gesetzt oder einige gelöscht sind oder beides.


Flaggen

Arithmetische und logische Operationen sind sehr hilfreich beim Setzen der Flags. Zum Beispiel haben wir nach einem sub eax, ebx für jetzt vorzeichenlose Werte:

Flagge Wenn eingestellt Wenn klar
ZF Wenn das Ergebnis Null ist.
EAX - EBX = 0 ⇒ EAX = EBX
Wenn das Ergebnis nicht Null ist.
EAX - EBX ≠ 0 ⇒ EAX ≠ EBX
CF Wann musste das Ergebnis für die MSB tragen.
EAX - EBX <0 ⇒ EAX <EBX
Wenn das Ergebnis für die MSB nicht erforderlich war.
EAX - EBX ≮ 0 ⇒ EAX ≮ EBX
SF Wenn das Ergebnis MSb eingestellt ist. Wenn das Ergebnis MSb nicht gesetzt ist.
VON Wenn ein signierter Überlauf aufgetreten ist. Wenn ein signierter Überlauf nicht auftreten.
PF Wenn die Anzahl der Bits, die im niedrigstwertigen Byte des Ergebnisses gesetzt sind, gerade ist. Wenn die Anzahl der Bits, die im niedrigstwertigen Byte des Ergebnisses gesetzt sind, ungerade ist.
AF Wenn die untere BCD-Ziffer einen Carry generiert hat.
Es ist Bit 4 Carry.
Wenn die untere BCD - Ziffer nicht erzeugte einen Übertrag.
Es ist Bit 4 Carry.

Zerstörungsfreie Prüfungen

Die Anweisungen sub und and ändern ihren Zieloperanden und würden zwei zusätzliche Kopien (Speichern und Wiederherstellen) erfordern, um das Ziel unverändert zu lassen.

Um einen zerstörungsfreien Test durchzuführen, gibt es die Anweisungen cmp und test . Sie sind identisch mit ihrem destruktiven Gegenstück, es sei denn, das Ergebnis der Operation wird verworfen und nur die Flags werden gespeichert .

destruktiv Nicht destruktiv
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

Signierte und nicht signierte Tests

Die CPU gibt den Werten 1 keine besondere Bedeutung, sign ist ein Programmer-Konstrukt. Beim Testen von vorzeichenbehafteten und nicht vorzeichenbehafteten Werten besteht kein Unterschied. Der Prozessor berechnet genug Flags, um die üblichen arithmetischen Beziehungen (gleich, kleiner als, größer als usw.) zu testen, sowohl wenn die Operanden als vorzeichenbehaftet und als nicht signiert betrachtet werden.


1 Es gibt zwar einige Anweisungen, die nur bei bestimmten Formaten sinnvoll sind, wie z. B. Zweierkomplement. Dies soll den Code effizienter machen, da die Implementierung des Algorithmus in Software viel Code erfordern würde.

Bedingte Sprünge

Basierend auf dem Zustand der Flags kann die CPU einen Sprung entweder ausführen oder ignorieren. Eine Anweisung, die basierend auf den Flags einen Sprung ausführt, fällt unter den generischen Namen Jcc - Jump on Condition Code 1 .

Synonyme und Terminologie

Um die Lesbarkeit des Assemblycodes zu verbessern, hat Intel mehrere Synonyme für denselben Bedingungscode definiert. Zum Beispiel sind jae , jnb und jnc derselbe Bedingungscode CF = 0 .

Während der Befehlsname einen sehr deutlichen Hinweis darauf geben kann, wann er verwendet werden soll oder nicht, besteht der einzige sinnvolle Ansatz darin, die Flags zu erkennen, die getestet werden müssen, und dann die Anweisungen entsprechend auszuwählen.
Intel gab den Anweisungen jedoch Namen, die nach einer cmp Anweisung cmp . Für die Zwecke dieser Diskussion wird angenommen, dass cmp die Flags vor einem bedingten Sprung gesetzt hat.

Gleichberechtigung

Die Operanden sind gleich, wenn ZF gesetzt wurde, sie unterscheiden sich ansonsten. Um die Gleichheit zu testen, benötigen wir 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)
Anweisung Flaggen
je , jz ZF = 1
jne , jnz ZF = 0

Größer als

Bei unsignierten Operanden ist das Ziel größer als die Quelle, wenn Carry nicht benötigt wurde, das heißt, wenn CF = 0 ist . Wenn CF = 0 ist , ist es möglich, dass die Operanden gleich sind, und der Test von ZF wird disambiguieren.

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

Für signierte Operanden müssen wir prüfen, ob SF = 0 ist , es sei denn, es wurde ein signierter Überlauf ausgeführt. In diesem Fall wird der resultierende SF umgekehrt. Da OF = 0 ist, wenn kein vorzeichenbehafteter Überlauf aufgetreten ist, andernfalls müssen wir prüfen, ob SF = OF ist .

Mit ZF kann ein strenger / nicht strikter Test durchgeführt werden.

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

Weniger als

Diese verwenden die umgekehrten Bedingungen von oben.

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

Bestimmte Flaggen

Jedes Flag kann einzeln mit j<flag_name> getestet werden, wobei Flag_Name nicht das nachfolgende F enthält (z. B. CFC , PFP ).

Die übrigen Codes, die zuvor nicht behandelt wurden, sind:

Anweisung Flagge
js SF = 1
jns SF = 0
jo OF = 1
jno OF = 0
jp , jpe (e = gerade) PF = 1
jnp , jpo (o = ungerade) PF = 0

Ein weiterer bedingter Sprung (extra)

Ein spezieller x86-bedingter Sprung testet keine Flagge. Stattdessen ecx es den Wert des Registers cx oder ecx (basierend auf dem aktuellen CPU- ecx , der 16 oder 32 Bit beträgt) und der Sprung wird ausgeführt, wenn das Register Null enthält.

Diese Anweisung wurde für die Validierung des Zählerregisters (entworfen cx/ecx ) vor rep -ähnlichen Anweisungen oder vor 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)
Anweisung Registrieren (nicht kennzeichnen)
jcxz , jecxz cx = 0 (16b-Modus)
jcxz , jecxz ecx = 0 (32b-Modus)

1 oder so ähnlich.

Arithmetische Beziehungen testen

Vorzeichenlose Ganzzahlen

Größer als

cmp eax, ebx
ja a_label  

Größer als oder gleich

cmp eax, ebx
jae a_label  

Weniger als

cmp eax, ebx
jb a_label  

Weniger als oder gleich

cmp eax, ebx
jbe a_label 

Gleich

cmp eax, ebx
je a_label 

Nicht gleich

cmp eax, ebx
jne a_label     

Signierte Ganzzahlen

Größer als

cmp eax, ebx
jg a_label  

Größer als oder gleich

cmp eax, ebx
jge a_label  

Weniger als

cmp eax, ebx
jl a_label  

Weniger als oder gleich

cmp eax, ebx
jle a_label 

Gleich

cmp eax, ebx
je a_label 

Nicht gleich

cmp eax, ebx
jne a_label 

a_label

In den obigen a_label ist a_label das Ziel für die CPU, wenn die getestete Bedingung "true" ist. Wenn die getestete Bedingung "false" ist, fährt die CPU mit dem nächsten Befehl nach dem bedingten Sprung fort.

Synonyme

Es gibt Anweisungs-Synonyme, die verwendet werden können, um die Lesbarkeit des Codes zu verbessern.
Zum Beispiel sind ja und jnbe (Jump nicht unter oder gleich) die gleiche Anweisung.

Signierte nicht signierte Begleitcodes

Operation Ohne Vorzeichen Unterzeichnet
> ja jg
> = jae jge
< jb jl
<= jbe jle
= je je
!,! =, <> jne jne


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow