2
    const char* p = rhs.digits; //temp pointer to rhs.digits.
    char* q = digits;   //temp to just digits
    _asm {
        mov EAX, 0      //clear register for addition
        mov ESI, p      //point to rhs.digits
        mov EDI, q      //point to digits
        add EDI, 4095  //last position of digits
        add ESI, 4095
        mov ECX, 4096   //set up loop
        L1:
            mov AL, [EDI]   //setup for addition
            add AL, [ESI]   //Add
            add AL, AH      //Add carry
            mov AH, 0       //Clear AH register
            AAA             //Adjust after addition
            mov [EDI], AL
            dec ESI
            dec EDI //move pointers
        loop L1
    }

这是一个用 C++ 编写的内联 asm 函数。Digits 是一个 4096 个字符长的字符数组,而 rhs.digits 是一个单独的数组。Digits 是目标,rhs.digits 是要添加到数字的数组。

我遇到的问题是当加法导致数字大于 15 时的进位。所以 8+8、8+9、9+9。我不是 100% 确定 AAA 是如何工作的,但我相信它会丢弃值的高位并将低位放入 AH。这意味着因为 16、17 和 18 不能用一个十六进制数字表示并且需要两个,所以高位位被丢弃并忽略。

这通过检查输出得到加强。如果 8+8 0 放在那个位置。如果是 8+9, 1 和 9+9, 2。这将对应于它们的十六进制表示。我尝试改用 DAA,但这也不起作用。

我怎样才能解决这个问题?如果有说明说明这一点?

谢谢你们的帮助。

4

1 回答 1

1

对于打包的BCD 值,您需要使用指令DAA例如

clc
L1:
mov AL, [EDI]
adc AL, [ESI]
daa
mov [EDI], AL
; etc

对于未打包的BCD 数字,您需要使用指令AAA ASCII Adjust After Addition),例如

clc
L1:
mov AL, [EDI]
adc AL, [ESI]
aaa                ; CF=AF=decimal carry-out from AL.  Also added to AH
mov [EDI], AL
; etc

请注意,进位标志在decandloop指令中仍然存在。

于 2018-04-28T18:46:02.303 回答