Двоично-десятичные числа (BCD-числа). Неупакованные BCD-числа.
Вычитание неупакованных BCD-чисел (макрокоманда)
sub_bcdmacro minuend.lenjn .deduction.len_d .difference local temp.ml.m2.exit_m :sub_bcd minuend".len_m.deduction,len_d.difference – макрокоманда вычитания : неупакованных BCD-чисел размером;len_m и len_d байт и помещение результата в difference. ;Вход: minuend и deduction – адреса младших байтов уменьшаемого и вычитаемого : len_m и len_d – длины уменьшаемого и вычитаемого в байтах. ;Выход: difference – адрес младшего байта поля разности. :Длина поля difference должна быть не меньше длины:уменьшаемого. ;Порядок следования байт – младший байт по младшему адресу (Intel). push si ;копируем уменьшаемое в difference: push ds pop es eld lea si.minuend lea di.difference mov cx.lenjn push ex rep movsb jmp ml;копируем вычитаемое во врем, область temp: temp db len_m dup (0) ml: lea si.deduction lea di,cs:temp mov cx.len_d push cs pop es rep movsb xor si.si pop ex m2: mov al,minuend[si] sbb al,cs:temp[si] aas mov difference[si].al inc si 1oop m2 jc m3:на обработку заема из старшего разряда jmp exit_m m3: пор exitjn: pop si end
Макрокоманда учитывает возможный заем из старших разрядов.
В дальнейшем нам понадобится и другой вариант этой команды – sub_bcd_r, который обрабатывает операнды с порядком следования байтов – старший байт по младшему адресу.
Умножение неупакованных BCD-чисел (макрокоманда)
.data k db 0:перенос 0 < к < 255 b dw 10;основание системы счисления .code mul_bcdmacro u.i.v.j.w * local m2.m4.m6 :mul_bcd u.i.v.j.w – макрокоманда умножения неупакованных :BCD-чисел u и v размером i и j байт и помещение результата :в w. ;Вход: и – адрес первого множителя; i – длина u: v – адрес ;второго множителя: j – длина v: w – адрес области :размерностью i+j байт, куда необходимо поместить :произведение: b=256 – размерность машинного слова. :Выход: w – произведение размерностью i+j байт. :Порядок следования байтов – младший байт по младшему адресу :(Intel). :сохраним регистры push si :очистим w eld push ds pop es xor al.al lea di,w mov ex,i+j rep stosb xor bx.bx;j=0..m-l mov CX.j m2: push ex: вложенные циклы CiTlp v[bx].O ' je m6 :m3 xor si,si:1=0..n-1 mov cx.i mov k.O m4: mov al,u[si] mul v[bx] xor dx.dx mov dl.w[bx+si] add ax.dx xor dx.dx mov dl,k add ax.dx;t-(ax) – временная переменная :корректируем результат – (аn)-цифра переноса:;(а1)=результат aam mov k.ah mov w[bx+si].al :m5 inc si loop m4 mov al.k mov w[bx+si],al m6: inc bx pop ex loop m2 pop si endm
Нам понадобится и другой вариант этой команды – mul_bcd_r, который обрабатывает операнды с порядком следования байтов – старший байт по младшему адресу.