Умножение двоичных чисел
Умножение чисел размером N и М байт с учетом знака
Как уже не раз отмечалось, система команд микропроцессора содержит два типа команд умножения – с учетом знаков операнда (IMUL) и без него (MUL). При умножении операндов размером 1/2/4 байта учет знака производится автоматически – по состоянию старших (знаковых) битов. Если умножаются числа размером в большее количество байтов, то для получения правильного результата необходимо учитывать знаковые разряды только старших байтов. В основе программы, реализующей алгоритм умножения чисел размером N и М байт с учетом знака, лежит рассмотренная выше процедура умножения чисел произвольной размерности без учета знака.
Умножение N-байтного числа на число размером М байт с учетом знака
ПРОГРАММА mul_sign_NM //--------------------------------------------------------- //mul_sign_NM – программа на псевдоязыке умножения N-байтного числа //на число размером М байт //(порядок – старший байт по младшему адресу (не Intel)) // Вход: U и V – множители со знаком размерностью N и М байт соответственно; //Ь=256 – размерность машинного слова. //Выход: W – модуль (дополнение) произведения размерностью N+M байт. //--------------------------------------------------------- ПЕРЕМЕННЫЕ INTJ3YTE u[n]; //множитель 1 размерностью N байт INT_BYTE v[n]; //:множитель 2 размерностью М байт INT_BYTE w[n+m]: k=0://перенос 0 < k < 255 INT_BYTE sign=0: //информация о знаке INT_WORD b=256: temp_word //b – размер машинного слова НАЧ_ПРОГ //определим знак результата ЕСЛИ БИТ_7_БАЙТА((и[0] AND 80h) XOR v[0])==1 TO sign: = 1 //результат будет отрицательным //получим модули сомножителей: u:-|u| v:-]v| w: = mul_unsign_NM() //в этой точке – модуль результата //восстанавливаем знак результата ЕСЛИ sign==0 TO ПЕРЕЙТИ_НА Шт //для отрицательного результата вычислить дополнение значения w длиной i+j w := calc_complement_r() //в этой точке – двоичное дополнение результата @йп: КОН_ПРОГ :mul_sign_NM.asm – программа на ассемблере умножения N-байтного числа :на число размером М байт ;(порядок – старший байт по младшему адресу (не Intel)) .data;значения в U и V нужно внести ;Помните. что задание отрицательных многобайтных значений в ;сегменте данных должно производиться в дополнительном коде ;(и в порядке байтов – старший байт по младшему адресу)! U db?:множитель 1 размерностью N байт i-$-U V db?;множитель 2 размерностью М байт J-$-V len_product=$-U W db len_product dup (0) результат длиной N+M байт k db 0;перенос О < k < 255 b dw lOOh;размер машинного слова sign db 0 информация о знаке .code ;включить описание процедур calc_complement_r .calc_abs_r.:mul_unsign_NM mul_sign_NM ргос;НАЧ_ПРОГ определим знак результата хог ах.ах; ЕСЛИ БИТ_7_БАЙТА((и[0] AND 80h) XOR v[0])==1 TO sign: = 1 mov al.u and al.80h xor al.v bt ax,7 jnc $+7 mov sign.l результат будет отрицательным lea bx.v;получим модули сомножителей: u:~|u|; v: = |v| mov ex.j call calc_abs_r 1 ea bx, u mov ex.i call calc_abs_r;теперь умножаем call mul_unsign_NM;w: = inul_unsign_NM();в этой точке – модуль результата ;восстанавливаем знак результата хог si .si emp sign.0:ЕСЛИ sign==0 ТО ПЕРЕЙТИ_НА №т je @@m://для отрицательного результата вычислить дополнение значения w длиной i+j mov ex,i+j;w: = calc_complement_r(); w[0]: = 0-w[0] lea bx.w call calc_complement_r;в этой точке – двоичное дополнение результата @@m: ret;КОН_ПРОГ mul_sign_NM endp main: call mul_sign_NM end main
Процедура mul_sign_NM выполняет умножение с учетом знака исходных значений в порядке байтов – старший байт по младшему адресу. Если вы используете отрицательные значения операндов, то для правильной работы тестовой программы в сегменте данных их необходимо задать в дополнительном коде.
В данной программе используются две новые процедуры – calc_complement_r и calc_abs_r, вычисляющие соответственно дополнение и модуль числа размером N байт. Подобные процедуры уже были разработаны и введены нами для значений, порядок следования байт которых характерен для микропроцессоров Intel. Чтобы различать эти две пары процедур, процедуры для вычисления дополнения и модуля числа размером байт с порядком следования байтов, отличным от Intel, мы назвали реверсивными.