x86程序集 - CMP未正确设置零标记

时间:2017-01-19 20:14:19

标签: assembly x86 compare cmp eflags

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

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

我在它上面设置了一个断点并看到了这个( hex 中的值):

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 vs JA)。比较之后是JNE,因为ZF = 0并且导致不正确的结果。

1 个答案:

答案 0 :(得分:4)

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

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

带有错误的调试器是x64dbg(尽管名称不同,它不仅适用于64位)。我的构建已经有点过时了,也许错误在最新的快照中得到修复。

感谢大家的评论。

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

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