2012-03-08 11 views
41

Nie rozumiem instrukcji JG/JNLE/JL/JNGE, które pojawiają się po CMP.Zespół - JG/JNLE/JL/JNGE po CMP

Na przykład, jeśli mam:

CMP al,dl 
jg label1 

Kiedy al=101; dl =200.

O co prosimy o jg? Czy to jest al>dl? lub al-dl>0?

samo prolbem następnego kodu:

test al,dl 
jg label1 

Nie rozumiem czego porównać, a na co pytamy „jg”.

Innymi słowy, nie rozumiem, kiedy chcemy przejść do etykiety 1, a kiedy nie.

Dzięki.

+2

To jest tak proste do sprawdzenia, czy próbowałeś napisać program, aby to zrobić? – karlphillip

Odpowiedz

93

Po wykonaniu cmp a,b flagi są ustawione tak, jakbyś obliczył a - b.

Następnie instrukcje typu: jmp sprawdzają te flagi, aby sprawdzić, czy należy wykonać skok.

Innymi słowy, pierwszy blok kodu masz (z moje komentarze dodane):

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

by przejść do label1 wtedy i tylko wtedy al była większa niż dl.

Jesteś prawdopodobnie lepiej myśleć o nim jako al > dl ale dwa wybory masz tam są matematycznie równoważne:

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

Trzeba być ostrożnym przy korzystaniu jg ponieważ zakłada zostały podpisane swoimi wartościami. Tak więc, jeśli porównasz bajtów 101 (101 w uzupełnieniu do dwóch) z 200 (-56 w uzupełnieniu do dwóch), ten pierwszy będzie w rzeczywistości większy. Jeśli nie jest to pożądane, powinieneś użyć równoważnego, niepodpisanego porównania.

Aby uzyskać więcej informacji na temat wyboru skoku, należy zapoznać się z poniższą sekcją pod kątem kompletności. Pierwsze tymi, gdzie podpisał-ności nie jest właściwe:

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

Następnie niepodpisane nich:

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

I wreszcie podpisane nich:

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

Przepraszam, kupuję, sprawdzam teraz: jeśli mam AL = 200, DL = 101. A więc AL> DL, i do tego musimy skakać (jak mówisz ..). Ale w tym przypadku SF = 0, OF = 1, co oznacza -> SF! = OF i jg nie miałoby miejsca. Czego mi brakuje? –

+1

@Adam, ponieważ 'jg' działa na _signed_ values ​​(200 w ośmiobitowym uzupełnieniu jest w rzeczywistości -56). Jeśli chcesz obsłużyć je jako niepodpisane wartości, użyj 'ja'. Zaktualizuję odpowiedź. – paxdiablo

+1

Warto zauważyć, że w składni gdb (GAS) kolejność argumentów dla cmp (cmpl) jest odwrócona, jak widać na https://en.wikibooks.org/wiki/X86_Assembly/Control_Flow, która zawiera zarówno Intel, jak i GAS warianty. – Nickolay

4

Wikibooks ma dość dobry podsumowanie jump instructions.Zasadniczo, nie ma właściwie dwa etapy:

cmp_instruction op1, op2 

który określa różne flagi w oparciu o wynik, a

jmp_conditional_instruction address 

który wykona skok w oparciu o wyniki tych flag.

Porównać (cmp) będzie zasadniczo obliczyć odejmowanie op1-op2, jednak nie jest to przechowywane; zamiast tego ustawiane są tylko wyniki flag. Więc jeśli zrobiłeś, to jest to samo, co powiedzenie eax-ebx - wtedy decydujesz na podstawie tego, czy jest to wartość dodatnia, ujemna, czy zero, które oznaczają flagi do ustawienia.

Bardziej szczegółowy numer referencyjny: here.

0

Polecenie JG oznacza po prostu: Skok, jeśli większy. Wynik poprzednich instrukcji jest przechowywany w niektórych flagach procesora (w tym sprawdzi, czy ZF = 0 i SF = OF) i instrukcja skoku działają zgodnie z ich stanem.

Powiązane problemy