Иллюстрированный самоучитель по задачам и примерам Assembler

Двоично-десятичные числа (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, который обрабатывает операнды с порядком следования байтов – старший байт по младшему адресу.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.