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

Двоично-десятичные числа (BCD-числа). Неупакованные BCD-числа.

Работай постоянно, не почитай работу для себя бедствием
или бременем и не желай себе за это похвалы и участия.
Общее благо – вот чего ты должен желать.

Марк Аврелий

Понятие о BCD-числах и элементарных действиях с ними приведены в уроке 8 "Арифметические команды" учебника. В отличие от действий с двоичными числами работа с BCD-числами в микропроцессоре реализована косвенно. В его системе команд нет инструкций, которые непосредственно выполняют основные арифметические действия над BCD-числами в том виде, как это делается для двоичных операндов. Тем более нет средств, которые каким-то образом учитывали бы знак. Все это должен делать сам программист. Ниже приведены макрокоманды, которые выполняют базовые арифметические операции над BCD-числами различной разрядности.


Перед тем как приступать к работе с BCD-числами, необходимо договориться о том, как будут представляться BCD-числа в оперативной памяти – старший разряд BCD-числа по старшему адресу или старший разряд BCD-числа по младшему адресу. Изменить фрагмент программы для поддержки того или иного способа представления чисел не представляет особого труда. Поэтому для однозначности рассуждений выберем естественный для микропроцессоров Intel порядок следования байтов – младший байт по младшему адресу.

Сложение неупакованных BCD-чисел (макрокоманда)

add_bcdmacro summand_i.1en_l,summand_2.1 en_2,sum local ml.m2.m3
:add_bcd summand_1.1en_l,summand_2.1en_2.sum – макрокоманда
:сложения неупакованных BCD-чисел размером 1еп_1 и len_2
:байт и помещение результата в sum.
:Вход: summand_i и summand_2 – адреса младших байтов
слагаемых; 1еп_1 и 1еп__2 – длины слагаемых в байтах.
;Выход: sum – адрес младшего байта поля суммы. Желательно.
:чтобы это поле имело длину на единицу больше, чем длина
:самого длинного слагаемого.
;Порядок следования байт – младший байт по младшему адресу (Intel).
push si
push bx
mov ax.len_l
cmp ax.len_2
jna m2
mov cx,len_l;длина большего для сложения (см. ниже)
push ex
mov cx,len_2;длина меньшего для сложения (см. ниже)
push ex
mov cx.ax
lea bx.summand_l:адрес большего источника для сложения
lea si,summand_2:адрес меньшего источника для movsb
jmp m3
т2: mov сх.1еп_2:длина большего для сложения (см. ниже)
push ex
mov cx.len_l;длина меньшего для сложения (см. ниже)
push ex
mov cx.len_2
lea bx.summand_2;адрес большего источника для сложения
lea si.summand_l:адрес меньшего источника для movsb m3
: заполняем sum нулями – длина определена выше:
eld
хог al.al
lea di .sum rep stosb;пересылка меньшего (по длине) BCD-числа в sum:
eld
push ds
pop es
lea di .sum:адрес источника см. выше
pop сх;длина была определена выше и соотв. меньшему ВСО-числу rep movsb
pop сх;дикл по большему
хоr si,si
ml: mov al.[bx][si]
adc al, sum[si]
aaa
mov sum[si].al
inc si
loop ml
adc sum[si].O
pop bx
pop si
endm

Макрокоманда обрабатывает байты, исходя из предположения, что младший байт слагаемых находится по младшему адресу. Слагаемые необязательно имеют одинаковую длину, но сумма должна иметь размер поля на единицу больше, чем длина самого длинного слагаемого. В начале процесса сложения в поле результата помещается меньшее (по длине) слагаемое.

Нам понадобится и другой вариант этой команды – addbedr, который обрабатывает операнды с порядком следования байтов – старший байт по младшему адресу.

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