4

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

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
4

2 回答 2

2

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

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

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

@Hans Passantrepe cmpsb不需要您初始化 Z 标志或除方向标志之外的任何其他标志。

于 2014-07-13T15:23:59.573 回答
1

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

英特尔程序员参考说 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. ECXin的选择CMP ECX, ECX没有任何意义……CMP EDX, EDX也可以,避免任何暗示这会担心计数!

  2. 没有必要为... 准备ZF标志,REPE所以如果ECX != 0不需要准备。

  3. 这些标志可以在REPE...之前设置为您喜欢的任何内容,无论它们设置为什么,如果它们被保留ECX == 0并被最后一个CMPS所做的替换,否则。

于 2014-07-14T10:10:31.047 回答