2012-03-08 7 views
41

Tôi không hiểu hướng dẫn JG/JNLE/JL/JNGE, xuất hiện sau CMP.Lắp ráp - JG/JNLE/JL/JNGE sau CMP

ví dụ, Nếu tôi có:

CMP al,dl 
jg label1 

Khi al=101; dl =200.

Trên những gì chúng tôi yêu cầu jg? Có phải trên al>dl? hoặc al-dl>0?

Cùng prolbem trên mã tiếp theo:

test al,dl 
jg label1 

Tôi không hiểu những gì chúng ta so sánh, và về những gì chúng tôi yêu cầu các "jg".

Nói cách khác, tôi không hiểu khi nào chúng tôi sẽ chuyển sang nhãn1 và khi chúng tôi không làm như vậy.

Cảm ơn.

+2

Điều này rất đơn giản để kiểm tra, bạn đã thử viết một chương trình để làm điều đó chưa? – karlphillip

Trả lời

93

Khi bạn thực hiện cmp a,b, cờ được đặt như thể bạn đã tính a - b.

Sau đó, các hướng dẫn loại jmp kiểm tra những cờ đó để xem liệu có nên thực hiện bước nhảy hay không.

Nói cách khác, khối đầu tiên của mã bạn có (với ý kiến ​​của tôi gia tăng):

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

sẽ nhảy đến label1 khi và chỉ khi al lớn hơn dl.

Bạn đang có lẽ tốt hơn hết suy nghĩ về nó như al > dl nhưng hai lựa chọn mà bạn có có mặt toán học là tương đương:

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

Bạn cần phải cẩn thận khi sử dụng jg bởi vì nó giả định giá trị của bạn đã được ký kết. Vì vậy, nếu bạn so sánh các byte 101 (101 trong hai bổ sung) với 200 (-56 trong phần bổ sung của hai), thì trước đây thực sự sẽ lớn hơn. Nếu đó không phải là những gì mong muốn, bạn nên sử dụng so sánh không dấu tương đương.

Xem here để biết thêm chi tiết về lựa chọn nhảy, được sao chép dưới đây để hoàn thành. Đầu tiên là những nơi đã đăng nhập Ness là không thích hợp:

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

Sau đó, những người unsigned:

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

Và, cuối cùng, những người ký tên:

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

Xin lỗi, tôi mua ngay bây giờ: Nếu tôi có AL = 200, DL = 101. Vì vậy, AL> DL, và cho rằng, chúng ta cần phải nhảy (như bạn nói ..). Nhưng trong trường hợp này, SF = 0, OF = 1, nghĩa là -> SF! = OF, và jg sẽ không xảy ra. Những gì tôi nhớ? –

+1

@Adam, vì 'jg' hoạt động trên các giá trị _signed_ (200 trong phần bổ sung 8 bit của hai thực tế là -56). Nếu bạn muốn xử lý chúng dưới dạng giá trị chưa ký, hãy sử dụng 'ja'. Tôi sẽ cập nhật câu trả lời. – paxdiablo

+1

Cần lưu ý rằng trong cú pháp gdb (GAS) thứ tự của toán hạng cho cmp (cmpl) được đảo ngược, như bạn có thể thấy trên https://en.wikibooks.org/wiki/X86_Assembly/Control_Flow, liệt kê cả Intel và GAS các biến thể. – Nickolay

4

Wikibooks có một khá tốt bản tóm tắt của jump instructions.Về cơ bản, có thực sự là hai giai đoạn:

cmp_instruction op1, op2 

Những bộ cờ khác nhau dựa trên kết quả, và

jmp_conditional_instruction address 

mà sẽ thực hiện bước nhảy dựa trên kết quả của những lá cờ.

So sánh (cmp) về cơ bản sẽ tính toán phép trừ op1-op2, tuy nhiên, điều này không được lưu trữ; thay vào đó chỉ gắn cờ kết quả được đặt. Vì vậy, nếu bạn đã làm cmp eax, ebx đó là giống như nói eax-ebx - sau đó quyết định dựa trên cho dù đó là tích cực, tiêu cực hoặc số không mà cờ để thiết lập.

Tham khảo chi tiết hơn here.

0

Lệnh JG chỉ đơn giản là: Nhảy nếu Lớn hơn. Kết quả của các hướng dẫn trước được lưu trữ trong các cờ xử lý nhất định (trong đó nó sẽ kiểm tra nếu ZF = 0 và SF = OF) và hành động lệnh nhảy theo trạng thái của chúng.