Assembly 组件-CMP后的JG/JNLE/JL/JNGE
我不理解CMP后面的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-类型指令
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,输出反转为相反 即,有符号操作以一种不可能的方式改变了符号(例如,正+正或负
/* 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