1

我在调试时遇到了这个比较:

| 38 19 | CMP BYTE PTR DS:[ECX], BL

我在上面设置了一个断点并看到了这个(十六进制的值):

ECX = 00838430
BYTE PTR[ECX]=[00838430]=55
EBX = 00000055 (BL = 55)
EFLAGS = 00000314 (CF=0 OF=0 SF=0 ZF=0 AF=1 PF=1)

所以我希望在执行这个比较之后设置零标志,因为 ECX 和 BL 指向的字节是相等的。然而,发生的事情是设置了溢出标志并且 ZF 保持为 0。比较之后:

EFLAGS = 00000A06 (CF=0 OF=1 SF=0 ZF=0 AF=0 PF=1)

为什么它会这样?它与有符号/无符号整数有关吗?我认为 CMP 是不可知的,即将比较结果解释为有符号/无符号是下面的分支指令会做的事情(例如 JG 与 JA)。比较之后是一个 JNE,因为 ZF=0 并导致不正确的结果。

4

1 回答 1

4

我怀疑调试器中存在某种错误,所以我尝试了另一个(OllyDbg v2),发现我发布的值确实正确,内存和 BL 中有 55。但是,在 Olly 下运行时,CMP 的行为与预期的一样正确,即设置了 ZF,但未执行跳转。

所以代码实际上是按预期工作的,问题出在调试器上。当代码不在调试器下运行时,它也可以正常工作。对于这个特定的代码,在没有调试器的情况下测试正确性有点困难和耗时,这就是为什么到目前为止我从来没有在没有调试器的情况下测试过它。该错误与断点或单步无关,因为它在运行时也无法正常工作。

有 bug 的调试器是 x64dbg(尽管有这个名字,但它不仅适用于 64 位)。我的构建已经有点过时了,也许该错误已在最新快照中修复。

感谢大家的评论。


这实际上是用户错误,而不是调试器中的错误。在 00838430 处设置了一个 INT3 断点,我忘记了,或者我暂时忘记了软件断点是如何工作的。无论如何,这种情况下内存的实际内容是 0xCC,但调试器显示的是原始字节。所以 CMP 的行为与它应有的完全一样。Ped7g 的第一条评论是正确的,我应该仔细检查内存内容。使用另一个调试器进行的第二次测试工作正常,只是因为我当时没有在 00838430 处设置断点。

http://i.imgur.com/iWKad22.jpg

于 2017-01-19T21:07:05.973 回答