汇编ADC(add with carry)操作

4
mov eax, ptr_to_num1 ; little endian
mov ebx, ptr_to_num2 ; little endian
xor ecx, ecx
xor edx, edx
clc
bytes_addition:
    mov dl, byte [eax+ecx] ; byte from shortest
    adc dl, byte [ebx+ecx]
    mov byte [eax+ecx], dl
    inc ecx
    cmp ecx, 4 ; counter, 
    jl bytes_addition

考虑以下代码:

EAX: 4F2252FF(大端)

EBX: 00DFFC00(大端)

这个加法的结果是错误的:50024fff(大端)。 它应该是50024eff。 看起来进位标志受到影响,但为什么呢?


如果你要在循环中使用 cmp,你需要将 clc 移到循环的顶部。 - David Hoelzer
我不这么认为... 这会一直将进位标志设置为0,但我使用的是ADC。 - Andrew
我的观点是CMP会修改进位标志。这意味着当循环开始下一次迭代时,它不一定处于您期望的状态。 - David Hoelzer
请参考https://dev59.com/FNeP0ogBFxS5KdRjoIka,了解如何在循环中不影响进位标志位,同时也不会引起部分标志位停顿的讨论(例如LEA/JECXZ)。在您的情况下,循环的完全展开(4x adc/mov)将是与您的循环一样多的指令。 - Peter Cordes
1个回答

6

cmp会影响进位标志,因此它被用于无符号比较。

你可以将ecx的值设为-4,然后使用jnz bytes_addition。由于已经有了inc指令,当ecx变为0时它会设置零标志位并且不会影响进位标志。

当然这个偏移量必须进行补偿,可以通过在循环之前给eax加4或者在寻址中添加4的偏移量来实现。


谢谢,我怀疑有问题,但不确定。 - Andrew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接