问题描述
我必须证明 JL
和 JNGE
是相同的,并且特别是两者的意思
" if (left op
我可以从大学讲座资源和 stackoverflow 中看到一些关于这个问题的想法。 (http://ee.usc.edu/~redekopp/cs356/slides/CS356Unit5_x86_Control.pdf 和 Why does x86 have the redundant JNGE instruction?)
但是我在oracle x86 assembly reference doc等官方文档上看到的,只是说JL
和JNGE
共享相同的操作,SF OF。
我宁愿提供一些官方文档,“
解决方法
如果两个助记符组合成相同的操作码,根据定义,机器将以相同的方式运行它们。 CPU只能看到机器码,不能看到asm源码。 (您不会在 asm 文档中看到 <
,因为这仅适用于由 cmp
或 sub
设置的 FLAGS。)
是的,从英特尔官方 PDF (https://www.felixcloutier.com/x86/jcc) 中截取的 https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html 证实 JL
是“少则跳短(SF≠ OF)。”
可能在 Intel 的第 1 卷中的某个地方,他们解释了 cmp
+ JCC 如何使助记符与它们命名的“语义意义”相匹配。另见Assembly - JG/JNLE/JL/JNGE after CMP
至于 FLAGS 设置,cmp x,y
就像 x - y
只是设置 FLAGS。如果 y 是更大的数字,结果将是负数(SF 集),除非您已签名溢出。有关如何通过减法设置 OF 的详细信息,请参阅 http://teaching.idallen.com/dat2343/10f/notes/040_overflow.txt。
注意两个等宽数的相减只能溢出一次,不能溢出并一直绕回负数(或与正确结果相同的符号)。
- 如果 SF=1 并且没有溢出,
x-y < 0
所以x < y
. - 如果 SF=0 并且没有溢出,
x-y >= 0
所以x < y
是不正确的 -
如果有溢出,SF与正确结果的符号位相反。(这正是有符号溢出,请参阅链接指南)。
SF != OF
是这两个位的异或:翻转 SF 以找到正确结果的符号,并参考适当的无溢出情况之一。
所以我们可以证明 SF != OF
是 cmp eax,edx
/ jl
的正确条件,当条件是 eax < edx
(签名)。 结合官方文档中将它们的操作描述为跳转 if SF != OF
,是的,我们已经证明了 JL
(和 JNGE
)匹配它们的助记符。如果您想通过定义 OF
的确切含义将其充实为更严格的证明,您可以。
如果你在不同的指令之后运行 jl
,比如 add eax,edx
,它仍然会检查这些标志,但它们的设置方式与一个人没有任何关系比另一个少。这就是为什么 <
不是 jl
本身的固有部分,只是在 {{1} 之后使用它会发生什么}. (或在 cmp
之后,它设置 FLAGS identically to cmp eax,0
,即与零的隐式比较,就像任何总是清除 OF 并根据结果设置 SF 和 ZF 的操作一样。)