webentwicklung-frage-antwort-db.com.de

Montage - JG / JNLE / JL / JNGE nach CMP

Ich verstehe das JG/JNLE/JL/JNGE Anweisungen, die nach CMP kommen.

zum Beispiel, wenn ich:

CMP al,dl
jg label1

Wann al=101; dl =200.

Worum bitten wir den jg? Ist es an al>dl? oder al-dl>0?

Gleiches Prolbem im nächsten Code:

test al,dl
jg label1

Ich verstehe nicht, was wir vergleichen und worum wir bitten "jg".

Mit anderen Worten, ich verstehe nicht, wann wir zu label1 springen würden und wann nicht.

51
Adam Sh

Wenn Sie einen cmp a,b Ausführen, werden die Flags so gesetzt, als hätten Sie a - b Berechnet.

Dann überprüfen die Anweisungen vom Typ jmp- diese Flags, um festzustellen, ob der Sprung ausgeführt werden soll.

Mit anderen Worten, der erste Codeblock, den Sie haben (mit meinen Kommentaren):

cmp al,dl     ; set flags based on the comparison
jg label1     ; then jump based on the flags

würde genau dann zu label1 springen, wenn al größer als dl wäre.

Sie sollten es sich wahrscheinlich besser als al > dl Vorstellen, aber die beiden Möglichkeiten, die Sie dort haben, sind mathematisch äquivalent:

al > dl
al - dl > dl - dl (subtract dl from both sides)
al - dl > 0       (cancel the terms on the right hand side)

Sie müssen vorsichtig sein, wenn Sie jg verwenden, da davon ausgegangen wird, dass Ihre Werte signiert wurden. Wenn Sie also die Bytes 101 (101 im Zweierkomplement) mit 200 (-56 im Zweierkomplement) vergleichen, ist das erstere tatsächlich größer. Wenn dies nicht gewünscht wurde, sollten Sie den entsprechenden vorzeichenlosen Vergleich verwenden.

Siehe hier für weitere Einzelheiten zur Sprungauswahl, der Vollständigkeit halber weiter unten wiedergegeben. Erstens diejenigen, bei denen die Unterschrift nicht angebracht ist:

+--------+------------------------------+-------------+--------------------+
|Instr   | Description                  | signed-ness | Flags              |
+--------+------------------------------+-------------+--------------------+
| JO     | Jump if overflow             |             | OF = 1             |
+--------+------------------------------+-------------+--------------------+
| JNO    | Jump if not overflow         |             | OF = 0             |
+--------+------------------------------+-------------+--------------------+
| JS     | Jump if sign                 |             | SF = 1             |
+--------+------------------------------+-------------+--------------------+
| JNS    | Jump if not sign             |             | SF = 0             |
+--------+------------------------------+-------------+--------------------+
| JE/    | Jump if equal                |             | ZF = 1             |
| JZ     | Jump if zero                 |             |                    |
+--------+------------------------------+-------------+--------------------+
| JNE/   | Jump if not equal            |             | ZF = 0             |
| JNZ    | Jump if not zero             |             |                    |
+--------+------------------------------+-------------+--------------------+
| JP/    | Jump if parity               |             | PF = 1             |
| JPE    | Jump if parity even          |             |                    |
+--------+------------------------------+-------------+--------------------+
| JNP/   | Jump if no parity            |             | PF = 0             |
| JPO    | Jump if parity odd           |             |                    |
+--------+------------------------------+-------------+--------------------+
| JCXZ/  | Jump if CX is zero           |             | CX = 0             |
| JECXZ  | Jump if ECX is zero          |             | ECX = 0            |
+--------+------------------------------+-------------+--------------------+

Dann die unsignierten:

+--------+------------------------------+-------------+--------------------+
|Instr   | Description                  | signed-ness | Flags              |
+--------+------------------------------+-------------+--------------------+
| JB/    | Jump if below                | unsigned    | CF = 1             |
| JNAE/  | Jump if not above or equal   |             |                    |
| JC     | Jump if carry                |             |                    |
+--------+------------------------------+-------------+--------------------+
| JNB/   | Jump if not below            | unsigned    | CF = 0             |
| JAE/   | Jump if above or equal       |             |                    |
| JNC    | Jump if not carry            |             |                    |
+--------+------------------------------+-------------+--------------------+
| JBE/   | Jump if below or equal       | unsigned    | CF = 1 or ZF = 1   |
| JNA    | Jump if not above            |             |                    |
+--------+------------------------------+-------------+--------------------+
| JA/    | Jump if above                | unsigned    | CF = 0 and ZF = 0  |
| JNBE   | Jump if not below or equal   |             |                    |
+--------+------------------------------+-------------+--------------------+

Und schließlich die unterschriebenen:

+--------+------------------------------+-------------+--------------------+
|Instr   | Description                  | signed-ness | Flags              |
+--------+------------------------------+-------------+--------------------+
| JL/    | Jump if less                 | signed      | SF <> OF           |
| JNGE   | Jump if not greater or equal |             |                    |
+--------+------------------------------+-------------+--------------------+
| JGE/   | Jump if greater or equal     | signed      | SF = OF            |
| JNL    | Jump if not less             |             |                    |
+--------+------------------------------+-------------+--------------------+
| JLE/   | Jump if less or equal        | signed      | ZF = 1 or SF <> OF |
| JNG    | Jump if not greater          |             |                    |
+--------+------------------------------+-------------+--------------------+
| JG/    | Jump if greater              | signed      | ZF = 0 and SF = OF |
| JNLE   | Jump if not less or equal    |             |                    |
+--------+------------------------------+-------------+--------------------+
107
paxdiablo

Wikibooks hat eine ziemlich gute Zusammenfassung von Sprunganweisungen . Grundsätzlich gibt es eigentlich zwei Stufen:

cmp_instruction op1, op2

Welche setzt verschiedene Flags basierend auf dem Ergebnis, und

jmp_conditional_instruction address

dieser Befehl führt den Sprung basierend auf den Ergebnissen dieser Flags aus.

Compare (cmp) berechnet grundsätzlich die Subtraktion op1-op2 wird jedoch nicht gespeichert; Stattdessen werden nur Flag-Ergebnisse gesetzt. Also wenn du es getan hast cmp eax, ebx das ist das gleiche wie sagen eax-ebx - Entscheiden Sie dann anhand der zu setzenden Flags, ob dies positiv, negativ oder null ist.

Detailliertere Referenz hier .

4
user257111

Addition und Subtraktion im Zweierkomplement sind für vorzeichenbehaftete und vorzeichenlose Zahlen gleich

Die wichtigste Beobachtung ist, dass CMP im Grunde genommen Subtraktion ist und:

In Zweierkomplement (von x86 verwendete Ganzzahldarstellung) sind vorzeichenbehaftete und vorzeichenlose Additionen genau dieselbe Operation

Dies ermöglicht beispielsweise Hardwareentwicklern eine effizientere Implementierung mit nur einer Schaltung.

Wenn Sie also beispielsweise dem x86-ADD-Befehl Eingabebytes zuweisen, ist es egal, ob diese signiert sind oder nicht.

ADD setzt jedoch einige Flags, je nachdem, was während des Vorgangs passiert ist:

  • übertragen: Das vorzeichenlose Additions- oder Subtraktionsergebnis passt nicht in die Bitgröße, z. B .: 0xFF + 0x01 oder 0x00 - 0x01

    Außerdem müssten wir 1 in die nächste Stufe befördern.

  • vorzeichen: Ergebnis hat oberes Bit gesetzt. Das heißt: ist negativ, wenn als signiert interpretiert.

  • überlauf: Die oberen Eingangsbits sind 0 und 0 oder 1 und 1, und der invertierte Ausgang ist das Gegenteil.

    Das heißt Signed Operation änderte die Signatur in unmöglicher Weise (z. B. positiv + positiv oder negativ)

Wir können diese Flags dann so interpretieren, dass der Vergleich unseren Erwartungen für vorzeichenbehaftete oder vorzeichenlose Zahlen entspricht.

Diese Interpretation ist genau das, was JA gegen JG und JB gegen JL für uns tun!

Codebeispiel

Hier ist GNU GAS ein Code-Snippet, um dies konkreter zu machen:

/* 0x0 ==
 *
 * * 0 in 2's complement signed
 * * 0 in 2's complement unsigned
 */
mov $0, %al

/* 0xFF ==
 *
 * *  -1 in 2's complement signed
 * * 255 in 2's complement unsigned
 */
mov $0xFF, %bl

/* Do the operation "Is al < bl?" */
cmp %bl, %al

Beachten Sie, dass die AT & T-Syntax "rückwärts" lautet: mov src, dst. Sie müssen also die Operanden mental umkehren, damit die Bedingungscodes mit cmp Sinn ergeben. In der Intel-Syntax wäre dies cmp al, bl

Nach diesem Punkt würden die folgenden Sprünge ausgeführt:

  • JB, weil 0 <255
  • JNA, weil! (0> 255)
  • JNL, weil! (0 <-1)
  • JG, weil 0> -1

Man beachte, wie in diesem speziellen Beispiel die Signifikanz z. JB ist vergeben, JL nicht.

Ausführbares Beispiel mit Behauptungen .

Equals/Negated-Versionen wie JLE/JNG sind nur Aliase

Ein Blick auf den Abschnitt "Jcc - Jump if Condition Is Met" in den Intel 64- und IA-32-Architekturen-Softwareentwicklerhandbüchern, Band 2 zeigt, dass die Codierungen identisch sind, zum Beispiel:

Opcode  Instruction  Description
7E cb   JLE rel8     Jump short if less or equal (ZF=1 or SF ≠ OF).
7E cb   JNG rel8     Jump short if not greater (ZF=1 or SF ≠ OF).

Der Befehl JG bedeutet einfach: Jump if Greater. Das Ergebnis der vorhergehenden Anweisungen wird in bestimmten Prozessor-Flags gespeichert (dabei würde geprüft, ob ZF = 0 und SF = OF) und die Sprunganweisung entsprechend ihrem Zustand handeln.

0
Lukasz