Умножение неупакованных BCD-чисел
На примере сложения и вычитания неупакованных чисел стало понятно, что стандартных алгоритмов для выполнения этих действий над BCD-числами нет и программист должен сам, исходя из требований к своей программе, реализовать эти операции.
Реализация двух оставшихся операций — умножения и деления — еще более сложна. В системе команд микропроцессора присутствуют только средства для производства умножения и деления одноразрядных неупакованных BCD-чисел.
Для того чтобы умножать числа произвольной размерности, нужно реализовать процесс умножения самостоятельно, взяв за основу некоторый алгоритм умножения, например “в столбик”.
Для того чтобы перемножить два одноразрядных BCD-числа, необходимо:
поместить один из сомножителей в регистр al (как того требует команда mul);
поместить второй операнд в регистр или память, отведя байт;
перемножить сомножители командой mul (результат, как и положено, будет в ax);
результат, конечно, получится в двоичном коде, поэтому его нужно скорректировать.
Для коррекции результата после умножения применяется специальная команда
aam (ASCII Adjust for Multiplication) — коррекция результата умножения для представления в символьном виде.
Она не имеет операндов и работает с регистром ax следующим образом:
делит al на 10;
результат деления записывается так: частное в al, остаток в ah.
В результате после выполнения команды aam в регистрах al и ah находятся правильные двоично-десятичные цифры произведения двух цифр.
В листинге 10 приведен пример умножения BCD-числа произвольной размерности на однозначное BCD-число.
Листинг 10. Умножение неупакованных BCD-чисел <1> masm <2> model small <3> stack 256 <4> .data <5> b db 6,7 ;неупакованное число 76 <6> c db 4 ;неупакованное число 4 <7> proizv db 4 dup (0) <8> .code <9> main: ;точка входа в программу <10> mov ax,@data <11> mov ds,ax <12> xor ax,ax <13> lenequ 2 ;размерность сомножителя 1 <14> xor bx,bx <15> xor si,si <16> xor di,di <17> mov cx,len ;в cx длина наибольшего сомножителя 1 <18> m1: <19> mov al,b[si] <20> mul c <21> aam ;коррекция умножения <22> adc al,dl ;учли предыдущий перенос <23> aaa ;скорректировали результат сложения с переносом <24> mov dl,ah ; запомнили перенос <25> mov proizv[bx],al <26> inc si <27> inc bx <28> loop m1 <29> mov proizv[bx],dl ;учли последний перенос <30> exit: <31> mov ax,4c00h <32> int 21h <33> end main |
Данную программу можно легко модифицировать для умножения BCD-чисел произвольной длины. Для этого достаточно представить алгоритм умножения “в столбик”. Листинг 10 можно использовать для получения частичных произведений в этом алгоритме. После их сложения со сдвигом получиться искомый результат.
Перед окончанием обсуждения команды aam необходимо отметить еще один вариант ее применения. Эту команду можно применять для преобразования двоичного числа в регистре al в неупакованное BCD-число, которое будет размещено в регистре ax: старшая цифра результата в ah, младшая — в al. Понятно, что двоичное число должно быть в диапазоне 0...99.