Montage – JG / JNLE / JL / JNGE na CMP

Ik begrijp de JG/JNLE/JL/JNGEinstructies, die na CMP komen.

Als ik bijvoorbeeld heb:

CMP al,dl
jg label1

wanneer al=101; dl =200.

Over wat we de jgvragen? Staat het op al>dl? of al-dl>0?

Dezelfde prolbeem in de volgende code:

test al,dl
jg label1

Ik begrijp niet wat we vergelijken, en over wat we de “jg” vragen.

Met andere woorden, ik begrijp het niet wanneer we naar Label1 zouden springen, en wanneer we dat niet zouden doen.


Antwoord 1, Autoriteit 100%

Wanneer u een cmp a,bdoet, worden de vlaggen ingesteld alsof u het a - bhebt berekend.

Dan de jmp-TYPE-instructies controleren die vlaggen om te zien of de sprong moet worden gedaan.

Met andere woorden, het eerste blok code dat u hebt (met mijn opmerkingen toegevoegd):

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

springt naar label1indien en alleen als algroter was dan dl.

U bent waarschijnlijk beter af, denk eraan als al>dlMaar de twee keuzes die u hebt zijn wiskundig equivalent:

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

U moet voorzichtig zijn bij gebruik van jgVoor zover het aangenomen dat uw waarden zijn ondertekend. Dus, als u de bytes 101 (101 in de aanvulling van twee) vergelijkt met 200 (-56 in de aanvulling van twee), zal de eerste daadwerkelijk groter zijn. Als dat niet gewenst was, zou u de equivalente niet-ondertekende vergelijking moeten gebruiken.

Zie hiervoor meer details over sprongselectie, hieronder weergegeven voor de volledigheid. Eerst degenen waar ondertekendheid niet gepast is:

+--------+------------------------------+-------------+--------------------+
|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            |
+--------+------------------------------+-------------+--------------------+

Dan de niet-ondertekende:

+--------+------------------------------+-------------+--------------------+
|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   |             |                    |
+--------+------------------------------+-------------+--------------------+

En tot slot de ondertekende:

+--------+------------------------------+-------------+--------------------+
|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    |             |                    |
+--------+------------------------------+-------------+--------------------+

Antwoord 2, autoriteit 3%

Wikibooks heeft een redelijk goede samenvatting van springinstructies. Er zijn eigenlijk twee fasen:

cmp_instruction op1, op2

Die verschillende vlaggen instelt op basis van het resultaat, en

jmp_conditional_instruction address

die de sprong zal uitvoeren op basis van de resultaten van die vlaggen.

Compare (cmp) berekent in principe de aftrekking op1-op2, maar dit wordt niet opgeslagen; in plaats daarvan worden alleen vlagresultaten ingesteld. Dus als je cmp eax, ebxdeed, is dat hetzelfde als zeggen eax-ebx– en vervolgens beslissen op basis van of dat positief, negatief of nul is welke vlaggen je moet instellen.

Meer gedetailleerde referentie hier.


Antwoord 3

Optellen en aftrekken in het complement van twee is hetzelfde voor getekende en niet-ondertekende getallen

De belangrijkste observatie is dat CMP in feite aftrekken is, en:

In two’s complement(integer-representatie gebruikt door x86), ondertekende en niet-ondertekende toevoeging zijn precies dezelfde bewerking

Hierdoor kunnen bijvoorbeeld hardwareontwikkelaars het efficiënter implementeren met slechts één circuit.

Dus als je bijvoorbeeld invoerbytes aan de x86 ADD-instructie geeft, maakt het niet uit of ze zijn ondertekend of niet.

ADD stelt echter wel een paar vlaggen in, afhankelijk van wat er tijdens de operatie is gebeurd:

  • carry: resultaat van optellen of aftrekken zonder teken past niet in bitgrootte, bijv.: 0xFF + 0x01 of 0x00 – 0x01

    Daarnaast zouden we 1 naar het volgende niveau moeten brengen.

  • teken: resultaat heeft topbit ingesteld. D.w.z.: is negatief indien geïnterpreteerd als ondertekend.

  • overloop: invoer top bits zijn zowel 0 als 0 of 1 en 1 en uitvoer omgekeerd is het tegenovergestelde.

    D.w.z. ondertekende bewerking veranderde de handtekening op een onmogelijke manier (bijv. positief + positief of negatief

We kunnen die vlaggen vervolgens zo interpreteren dat de vergelijking overeenkomt met onze verwachtingen voor ondertekende of niet-ondertekende nummers.

Deze interpretatie is precies wat JA vs JG en JB vs JL voor ons doen!

Codevoorbeeld

Hier is GNU GAS een codefragment om dit concreter te maken:

/* 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

Merk op dat de AT&T-syntaxis “achterwaarts” is: mov src, dst. Dus je moet mentaal de operanden omdraaien om de conditiecodes logisch te maken met cmp. In Intel-syntaxis zou dit cmp al, bl

. zijn

Na dit punt zouden de volgende sprongen worden gemaakt:

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

Merk op hoe in dit specifieke voorbeeld de ondertekendheid van belang was, b.v. JB is bezet, maar niet JL.

Uitvoerbaar voorbeeld met beweringen.

Gelijk aan/ontkende versies zoals JLE/JNG zijn slechts aliassen

Door te kijken naar de Intel 64 en IA-32 Architectures Software Developer’s Manuals Volume 2sectie “Jcc – Jump if Condition Is Vold” zien we dat de coderingen identiek zijn, voor voorbeeld:

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).

Antwoord 4

Het commando JG betekent simpelweg: Spring indien groter. Het resultaat van de voorgaande instructies wordt opgeslagen in bepaalde processorvlaggen (hierin zou het testen of ZF=0 en SF=OF) en springinstructies werken volgens hun status.

Other episodes