Assembly 组件-CMP后的JG/JNLE/JL/JNGE

Assembly 组件-CMP后的JG/JNLE/JL/JNGE,assembly,x86,eflags,Assembly,X86,Eflags,我不理解CMP后面的JG/JNLE/JL/JNGE说明 例如,如果我有: CMP al,dl jg label1 当al=101时;dl=200 关于我们所问的jg?它在dl上吗?还是al dl>0 下一个代码上的相同prolbem: test al,dl jg label1 我不明白我们在比较什么,也不明白我们在问什么“jg” 换句话说,我不明白什么时候我们会跳到label1,什么时候我们不会跳到label1。当你做aCMPA,b时,标志设置就好像你已经计算了a-b 然后,jmp-类型指令

我不理解CMP后面的
JG/JNLE/JL/JNGE
说明

例如,如果我有:

CMP al,dl
jg label1
al=101时;dl=200

关于我们所问的
jg
?它在dl上吗?还是
al dl>0

下一个代码上的相同prolbem:

test al,dl
jg label1
我不明白我们在比较什么,也不明白我们在问什么“
jg


换句话说,我不明白什么时候我们会跳到label1,什么时候我们不会跳到label1。

当你做a
CMPA,b
时,标志设置就好像你已经计算了
a-b

然后,
jmp
-类型指令检查这些标志,看看是否应该进行跳转

换句话说,您拥有的第一块代码(添加了我的注释):

当且仅当
al
大于
dl
时,将跳转到
label1

您最好将其看作是
al>dl
,但您有两种选择在数学上是等价的:

al > dl
al - dl > dl - dl (subtract dl from both sides)
al - dl > 0       (cancel the terms on the right hand side)
使用
jg
时需要小心,因为它假定您的值已签名。因此,如果将字节101(101在两个补码中)与200(56在两个补码中)进行比较,前者实际上会更大。如果这不是所希望的,那么应该使用等效的无符号比较

有关跳转选择的更多详细信息,请参阅,完整性请参见下文。首先是那些不合适的地方:

+--------+------------------------------+-------------+--------------------+
|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            |
+--------+------------------------------+-------------+--------------------+
然后是未签名的:

+--------+------------------------------+-------------+--------------------+
|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   |             |                    |
+--------+------------------------------+-------------+--------------------+
+--------+------------------------------+-------------+--------------------+
|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    |             |                    |
+--------+------------------------------+-------------+--------------------+
最后,签署的文件:

+--------+------------------------------+-------------+--------------------+
|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   |             |                    |
+--------+------------------------------+-------------+--------------------+
+--------+------------------------------+-------------+--------------------+
|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    |             |                    |
+--------+------------------------------+-------------+--------------------+
+--------+------------------------------+-------------+--------------------+
|仪表|说明|签名|标志|
+--------+------------------------------+-------------+--------------------+
|JL/|如果小于|签名| SF则跳转|
|JNGE |不大于或等于跳转| ||
+--------+------------------------------+-------------+--------------------+
|JGE/|大于或等于时跳转|有符号| SF=OF|
|JNL |如果不小于| |跳转|
+--------+------------------------------+-------------+--------------------+
|JLE/|如果小于或等于|有符号| ZF=1或SF OF|
|JNG |如果不是更大,则跳跃||
+--------+------------------------------+-------------+--------------------+
|JG/|如果大于|有符号| ZF=0且SF=OF,则跳转|
|JNLE |如果不小于或等于,则跳转| ||
+--------+------------------------------+-------------+--------------------+

维基百科对这一问题有一个相当好的总结。基本上,有两个阶段:

cmp_instruction op1, op2
根据结果设置各种标志,以及

jmp_conditional_instruction address
将根据这些标志的结果执行跳转

Compare(
cmp
)将基本上计算减法
op1-op2
,但是,这不会被存储;相反,只设置标志结果。因此,如果你做了
cmp-eax,ebx
,这与说
eax-ebx
是一样的,然后根据它是正、负还是零来决定要设置哪些标志


更详细的参考。

命令JG的简单意思是:如果更大,则跳转。上述指令的结果存储在某些处理器标志中(在此标志中,它将测试ZF=0和SF=of),跳转指令根据它们的状态进行操作。

两个补码中的加减对于有符号和无符号数字是相同的。

关键观察结果是CMP基本上是减法,并且:

在(x86使用的整数表示)中,有符号和无符号加法是完全相同的操作

例如,这允许硬件开发人员使用一个电路更有效地实现它

因此,例如,当您为x86 ADD指令提供输入字节时,并不关心它们是否已签名

但是,ADD会根据操作过程中发生的情况设置一些标志:

  • 进位:无符号加减结果不适合位大小,例如:0xFF+0x01或0x00-0x01

    此外,我们需要将1带到下一个级别

  • 符号:结果已设置顶部位。即:如果解释为有符号,则为负值

  • 溢出:输入顶端位同时为0和0或1和1,输出反转为相反

    即,有符号操作以一种不可能的方式改变了符号(例如,正+正或负

然后,我们可以用一种方式来解释这些标志,使比较符合我们对有符号或无符号数字的期望

这种解释正是JA对JG和JB对JL为我们所做的

代码示例

以下是GNU GAS代码片段,使其更具体:

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

这很容易测试,你试过写一个程序来做吗?
test
使用两个不同的寄存器然后
jg
非常奇怪。但是由于
test
/
总是清除,它就像
jns
一样,但也会跳到ZF=0。我假设这只存在于一个虚构的示例中,以便让你分解标志-设置和标记阅读,而不使用任何正常的语义来帮助您了解它的功能。无论如何,
test dl,dl
/
jg
作为一个窥视孔优化来节省代码大小是完全正常的,但在其他方面与
cmp dl,0
/
jg
完全一样。对不起,我现在就买它:如果我有AL=200,dl=101.因此,AL>DL,为此,我们需要跳转(如您所说)。但在这种情况下,SF=0,OF=1,意思是->SF!=OF,和jg将不会发生。我错过了什么?@Adam,因为
jg
对有符号值起作用(8位2的补码中的200实际上是-56)。如果您想将它们作为无符号值处理,请使用
ja