【问题标题】:x86 assembly - CMP not setting zero flag correctlyx86 程序集 - CMP 未正确设置零标志
【发布时间】:2017-01-19 20:14:19
【问题描述】:

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

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

【问题讨论】:

  • 通常CMP 确实设置了正确的标志,并且您显示的值表明应该设置 ZF,所以我 99% 确定您描述的值之一是不正确的。我会先验证内存内容,你确定ds:[ecx] 有 55 个吗?你是怎么得到那个号码的?这是 32b 模式与平面内存模型(ds = 那时不重要)吗?
  • 请记住CMP 确实正确设置了标志。责怪代码,而不是处理器。
  • 好吧,从技术上讲,您可能已经损坏了 CPU,在 CMP 之后产生了不正确的标志,但除非这是由于 X 射线碰撞/等而导致的电子游荡的一次性事故。 (可能会发生,随着日常生活中 HW 的数量,至少有少数目前活着的人类会在他们的生活中至少遇到一次这种情况......尽管他们很可能不会注意到),它会产生很多坏的结果,您永远无法启动操作系统并运行调试器...因此,如果您不相信cmp,请再试一次,仅此而已,搜索周围的问题。

标签: assembly x86 compare cmp eflags


【解决方案1】:

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

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

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

感谢大家的cmets。


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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多