【发布时间】:2011-02-17 22:15:44
【问题描述】:
(ia32) 例如,
test $eax, $eax
你为什么要这样做?是$eax & $eax,对吧?这不应该总是设置标志寄存器说他们是平等的......?
附录: 所以如果寄存器为零,测试将设置 ZF(如下所述)。那么测试(如上所述)是否主要用于判断寄存器是否为空?如果是,那么 ZF 是否设置?
【问题讨论】:
标签: testing cpu-registers x86
(ia32) 例如,
test $eax, $eax
你为什么要这样做?是$eax & $eax,对吧?这不应该总是设置标志寄存器说他们是平等的......?
附录: 所以如果寄存器为零,测试将设置 ZF(如下所述)。那么测试(如上所述)是否主要用于判断寄存器是否为空?如果是,那么 ZF 是否设置?
【问题讨论】:
标签: testing cpu-registers x86
如果寄存器为零,它将设置ZF(零标志)。这可能是它最常用于测试的内容。它还会适当地设置其他标志,但这些标志的用途可能要少得多。
另外,我应该提到test 并没有真正执行比较 - 它执行按位and 操作(丢弃结果,除了标志)。
要执行操作数的比较,将使用cmp 指令,该指令执行sub 操作,丢弃除标志之外的结果。你说得对
cmp $eax, $eax
没有多大意义,因为每次都会根据零结果设置标志。
【讨论】:
ZF 未设置,jne 将跳转(jne 等效于 jnz - 因为它们是相同的操作码)。
这是设置零标志,就像使用or $eax,$eax 也可以非破坏性地测试零标志一样。
【讨论】:
它在处理器上设置 Z 和 S 标志,因此您可以在“test eax,eax”(或任何其他寄存器 8、16、32,我认为是 64 位)之后判断值是否为零,或者如果分别使用“je/jne/jz/jnz”或“js/jns”设置符号位。在为 x80/x86 架构编码的 30 年中,我已经用大多数寄存器组合完成了很多次。 (你不要在 ESP 的实践中使用它!)
IIRC,还计算了一个奇偶校验位,因此通过此测试,您可以使用“jp/jnp”判断寄存器中设置的位数是偶数还是奇数。我从来没有用过这个。
【讨论】:
此指令并非仅检查%eax 的值是否为零。它可以作为一个整体用于检查值%eax 是否为零或正或负。
以这种方式使用它的最大优点是它不会修改%eax 的值(在执行%eax & %eax 之后,它只是丢弃该值)并设置条件标志如下。
如果 %eax 值为零,OF, CF, ZF = 0(设置为零)
否则SF = MSB of the result(这里,结果是%eax & %eax)。所以如果数字是负数,我们得到SF = 1,否则得到SF = 0。
【讨论】: