在x86/x86_64中,如何才能"jump if not zero"不影响进位标志呢?

In x86/x86_64, how can I "jump if not zero" without affecting the carry flag?

我有这个循环,它基本上添加了两个动态宽度的整数(实际上,它展开了一点,但这并不重要)。寄存器 RCX 包含目标地址,RDX 包含源地址,R8 包含数组的长度。

    clc                    # Clear CF flag before beginning
.Lloop0:
    movq    (%rdx), %rax   # Load memory for next addition
    adcq    %rax, (%rcx)   # Perform addition with carry (i.e. using CF flag)
    leaq    8(%rcx), %rcx  # Increment destination address (without affecting CF)
    leaq    8(%rdx), %rdx  # Increment source address (without affecting CF)
    leaq    -1(%r8), %r8   # Decrement length (without affecting CF)
    testq   %r8, %r8       # Test if length is zero (affects CF!)
    jne     Lloop0

问题是TEST指令清除了CF标志,这是下一个ADC所需要的。 CMP 指令也有类似的效果。

我当然可以在测试前使用 LAHF 复制 FLAGS 寄存器并在循环开始时使用 SAHF 恢复它,但我想避免如果有办法解决它。

您可以交换上面 %r8%rcx 的角色以产生:

    clc
    .p2align 4 # just a thought...
.Lloop0:
    jrcxz .Lloop0_end
    ...
    leaq  -1(%rcx), %rcx
    jmp   .Lloop0
.Lloop0_end: