Распакованный десятичный формат в ошибках сборки x86, когда сложение больше 15 - PullRequest
0 голосов
/ 28 апреля 2018
    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
    }

Это встроенная функция asm, написанная на C ++. Цифры - это массив символов длиной 4096 символов, а rhs.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, но это тоже не сработало.

Как я могу это исправить? Если есть инструкция, которая объясняет это?

Спасибо за помощь, ребята.

1 Ответ

0 голосов
/ 28 апреля 2018

Для упакованных значений 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

Обратите внимание, что Carry Flag остается в живых после инструкций dec и loop.

...