Справочник по языку Ассемблера IBM PC

     

Умножение неупакованных 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. 



      Содержание раздела