在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:
我有这个循环,它基本上添加了两个动态宽度的整数(实际上,它展开了一点,但这并不重要)。寄存器 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: