assembly – CMP后的JG / JNLE / JL / JNGE
我不明白CMP之后的JG/JNLE/JL/JNGE
指令。
例如,如果我有:
CMP al,dl jg label1
当al=101; dl =200
al=101; dl =200
。
关于我们问什么jg
? 这是在al>dl
? 或al-dl>0
?
下一个代码也是一样的:
test al,dl jg label1
我不明白我们比较什么,以及我们问什么“ jg
”。
换句话说,我不明白我们什么时候会跳到标签1,什么时候我们不会。
谢谢。
当你做一个cmp a,b
,标志被设置,就像你已经计算出a - b
。
然后jmp
-type指令检查这些标志以查看是否应该进行跳转。
换句话说,你有第一块代码(加上我的意见):
cmp al,dl ; set flags based on the comparison jg label1 ; then jump based on the flags
会跳到label1
当且仅当al
大于dl
。
你可能更喜欢把它当作al > dl
但是你在那里有两个select在math上是等价的:
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 | | | +--------+------------------------------+-------------+--------------------+
Wikibooks对跳转指令有一个相当好的总结。 基本上,有两个阶段:
cmp_instruction op1, op2
根据结果设置各种标志
jmp_conditional_instruction address
它将根据这些标志的结果执行跳转。
比较( cmp
)将基本上计算减法op1-op2
,但是,这不被存储; 而是只设置标志结果。 所以如果你做了cmp eax, ebx
eax-ebx
– 然后根据是否为正值,负值或零来决定要设置哪些标志。
这里更详细的参考。
命令JG仅仅意味着: 如果更大则跳转 。 前面指令的结果存储在某些处理器标志中(在这里它将testingZF = 0和SF = OF),跳转指令根据它们的状态而动作。