x86 – 如果前面加上“add”命令,“jb”表示什么?

假设我在x86中有以下说明

add dh, dl            ; These are both unsigned integers.
jb loc_123456

在这种情况下,jb意味着什么?一般来说,它意味着“如果低于标准跳跃”,但我不确定这意味着什么.

最佳答案
根据Intel’s Software Developer’s Manual“JB”代表“跳下如果”

5.1.7 Control Transfer Instructions
The control transfer instructions provide jump, conditional jump, loop, and call and return operations to control program flow.

  • JE/JZ Jump if equal/Jump if zero
  • JNE/JNZ Jump if not equal/Jump if not zero
  • JA/JNBE Jump if above/Jump if not below or equal
  • JAE/JNB Jump if above or equal/Jump if not below
  • JB/JNAE Jump if below/Jump if not above or equal
  • JBE/JNA Jump if below or equal/Jump if not above
  • JG/JNLE Jump if greater/Jump if not less or equal
  • JGE/JNL Jump if greater or equal/Jump if not less
  • JL/JNGE Jump if less/Jump if not greater or equal
  • JLE/JNG Jump if less or equal/Jump if not greater
  • JC Jump if carry
  • JNC Jump if not carry
  • JO Jump if overflow
  • JNO Jump if not overflow
  • JS Jump if sign (negative)
  • JNS Jump if not sign (non-negative)
  • JPO/JNP Jump if parity odd/Jump if not parity
  • JPE/JP Jump if parity even/Jump if parity

x86条件分支只识别8种类型的条件(及其反转,因此总共16种).你使用哪种助记符(同义词)取决于具体情况,通常你会使用更有意义的东西.如果你反汇编代码,那么反汇编程序可能不够聪明,无法选择最有意义的选择.请注意,在上面的列表中,英特尔列出了18个条件跳转而不是16个,这是因为

> JB / JNAE / JC都汇编到同一条指令
> JAE / JNB / JNC都汇编到相同的指令

Here’s a convenient table将同义词组合在一起.

JB通常在“CMP”之后使用,类似这样

cmp dh,dl
jb loc_123456      ; jump if DH is below DL

如果设置了Carry标志,则“JB”分支.如前所述,您也可以使用JNAE执行相同的条件分支“如果不高于或等于跳跃”

cmp dh,dl
jnae loc_123456    ; jump if DH is not above or equal to DL

或与“JC”

cmp dh,dl
jc loc_123456      ; jump if there was a carry (borrow) when subtracting DL from DH

在你的情况下,它可能是一个更好的选择使用“JC”,如果携带设置跳跃

add dh, dl            ; These are both unsigned integers.
jc loc_123456         ; Jump if carry set

将条件分支视为测试前一条指令的结果是很方便的 – 但是在x86架构中定义的方式是EFLAGS寄存器是一个保存结果条件代码的“中间人”.某些指令(通常是算术,逻辑,比较)更新EFLAGS寄存器以指示操作的结果,并且条件分支指令依次使用EFLAGS寄存器来确定是否采用分支.

关于哪些EFLAGS位由指令计算有一些神秘的规则,有时总是设置为1或0而不管操作数如何,对于其他指令,某些EFLAGS位未定义,并且一些指令保留某些EFLAGS位(由指令保持不变).例如,INC和DEC指令保留EFLAGS中的进位标志的内容.旋转指令更新Carry和Overflow标志并保留其他标志,如果计数大于1,则旋转后溢出标志未定义…等.

这是一个人为的例子.在此示例中,条件分支测试在两个不同的8位寄存器上操作的两个不同指令的结果.

rol   dl,1
inc   dh
jnbe  loc_123456

ROL旋转指令将DL向左旋转一位,将EFLAGS进位标志设置为旋转的最后一位. INC指令将DH递增1,保留EFLAGS进位标志,设置EFLAG中的其他运算标志. JNBE是“如果不低于或等于跳跃”,如果EFLAGS进位标志为零并且EFLAGS零标志清零则分支.如果在递增DH之后DH寄存器不为零,则清零零标志(除非DH为0xFF并且将其递增后包装为0x00,否则为零).进位标志被设置为匹配左旋转的最后一位,换句话说,旋转左后的DL的最低有效位(之前是最高位).如果你把它想象为“如果不低于或等于跳跃”,JNBE没有意义,但如果你认为它只是测试Carry标志和Zero标志是否为零,那么它可能是有意义的.

转载注明原文:x86 – 如果前面加上“add”命令,“jb”表示什么? - 代码日志