【问题标题】:Why take CMP ECX, ECX?为什么要选择 CMP ECX、ECX?
【发布时间】:2014-07-13 07:37:41
【问题描述】:

我正在查看一些程序集,我看到了这条线

CMP ECX, ECX

这对我来说没有意义,因为它不总是正确的 A==A 吗? (自反性质)

不确定这是否会有所帮助,但在这种情况下使用它:

CPU Disasm
Address   Hex dump          Command                                         Comments
00414A24  |.  39C9          CMP ECX,ECX
00414A26  |.  F3:A6         REPE CMPS BYTE PTR DS:[ESI],BYTE PTR ES:[EDI]
00414A28  |.  0F92C0        SETB AL
00414A2B  |.  0F97C2        SETA DL
00414A2E  |.  28C2          SUB DL,AL
00414A30  |.  0FBEC2        MOVSX EAX,DL

【问题讨论】:

  • 我唯一的猜测是可能重置 0 标志?但我不完全明白这对这里有什么帮助
  • 考虑一下如果你省略了cmp ecx, ecxecx 恰好为零会发生什么。
  • ´rep´ 和loop 指令先递减ecx,然后检查标志。
  • 您能否给出更完整的答案作为解决方案?我将能够接受它作为一种解决方案并更好地理解(我可以称之为循环对吗?)循环。 SETA 和 SETB 也有点令人困惑,并且可以真正使用您在此 sn-p 上拥有的所有信息。

标签: assembly cmp


【解决方案1】:

如果 ECX 寄存器为零,则根本不执行 repe cmpsb。 这意味着下面的setbseta 指令会产生垃圾!

因此,程序员选择确保标志具有已定义的状态。 在这种情况下,cmp ecx,ecx 导致 CarryFlag=0 和 ZeroFlag=1。 setb 将使 AL 为零,seta 将使 DL 为零。

@user35443 repe cmpsb 不会预先减少 ECX。重复检查 ECX 是否为零,否则将在后递减。

@Hans Passant repe cmpsb 不需要你初始化 Z 标志,也不需要你初始化方向标志以外的任何其他标志。

【讨论】:

    【解决方案2】:

    正如@user3144770 所说...CMP ECX, ECX 清除CFZF(以及其他),因为如果计数从零开始,REPE CMPS ... 什么都不做——包括 not 影响标志。

    英特尔程序员参考中提到了 REP/REPE/等:

    WHILE CountReg ≠ 0
      DO
        Service pending interrupts (if any);
        Execute associated string instruction;
        CountReg ← (CountReg – 1);
        IF CountReg = 0
          THEN exit WHILE loop; FI;
        IF (Repeat prefix is REPZ or REPE) and (ZF = 0)
        or (Repeat prefix is REPNZ or REPNE) and (ZF = 1)
          THEN exit WHILE loop; FI;
      OD;
    

    为免生疑问:

    1. CMP ECX, ECX 中选择ECX 没有任何意义……CMP EDX, EDX 也可以,避免任何暗示这会担心计数!

    2. 不需要REPE 设置ZF 标志...所以如果ECX != 0 不需要准备。

    3. 1234563 /p>

    【讨论】:

    • cmp 不写入ecx,只写入标志。编辑了一些关于将rcx 截断为 32 位的废话。
    猜你喜欢
    • 2016-08-08
    • 2012-09-07
    • 1970-01-01
    • 2020-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多