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

Умножение двоичных чисел

mul_unsign_NM proc
mov bx.j-1:ml
mov ex, j;ДЛЯ j: = M-l ДО 0 //J изменяется в диапазоне М-1..0
m2::НАЧ_БЛОК_1
push ex сложенные циклы
emp v[bx],0:ЕСЛИ v[j]– 0 TO ПЕРЕЙТИ_НА m6
je m6;m3
movsi.i-1:i-0..n-l;k: = 0; 1:41-1 //i изменяется в диапазоне N-1.,0
mov cx.i
movk.O:ДЛЯ i:-N-l ДО О НАЧ_БЛ0К_2 m4:://перемножаем очередные элементы множителей
mov al,u[s1]:temp_word:-u[i]*v[j]+w[i+j+l]+k
mul byte ptr v[bx]
xor dx.dx
mov dl,w[bx+si+l]
add ax.dx
xor dx.dx
mov dl, k
add ax.dx:t=(ax) – временная переменная
:w[i+j+l]: = temp_word MOD b //остаток от деления temp_word\b › w[i+j+l]:k: = temp_word\b
//целая часть частного temp_word\b › k
push dx
xor dx.dx
div b
mov ah.dl
popdx
mov k.al
mov w[bx+si+l].ah:m5.
dec si
loop m4;КОН_БЛ0К_2
moval.k;w[j]: = k
mov w[bx].al m6: dec bx
pop ex
loop m2;КОН_БЛОК_1
ret;КОН_ПРОГ mul_unsign_NM endp main:
call mul_unsign_NM end main

В отличие от обычного умножения "в столбик" в данном алгоритме сложение частичных произведений выполняется параллельно умножению. Программа производит умножение значений в порядке – старший байт по младшему адресу. Это неестественно для микропроцессоров Intel, поэтому программу необходимо соответствующим образом изменить. Текст измененной процедуры mul_ unsign_NM_I приведен на дискете.

Процедуру умножения чисел без учета знака mul_unsign_NM удобно представить в виде макрокоманды mul_unsign_NM_r u,i,v, j,w. Это без излишних усложнений сделает ее вызов более универсальным. При последующем рассмотрении программы деления многобайтных двоичных чисел она будет использована нами с большой пользой. Текст макрокоманды приведен на дискете. На дискете также имеется вариант этой макрокоманды mul_unsign_NM u,i,v, j.W. Ha случай естественного для микропроцессоров Intel расположения операндов – младший байт по младшему адресу.

Умножение чисел размером 1 байт с учетом знака

;mul_sign.asm – программа умножения чисел размером 1 байт с учетом знака
;Вход: multiplier], и multiplied – множители со знаком размерностью 1 байт.
;Выход: product – значение произведения.
.data значения в multiplier], и multiplied нужно внести
product label word
productj label byte
multiplierl db?;множитель 1 (младшая часть произведения)
product_h db 0:старшая часть произведения
multiplied db?:множитель 2
.code
mul_sign proc
mov al.multiplierl
imul multiplied:оценить результат:
jnc no_carry:нет переполнения – на no_carry обрабатываем ситуацию переполнения
mov productji.ah:старшая часть результата, знак результата – старший бит product_h no_carry
: mov productj,al:младшая часть результата, productji – расширение знвка
ret
mul_sign endp .main:
call mul_sign end main

Аналогично умножению без знака здесь также все достаточно просто и реализуется средствами самого процессора. Проблема та же – правильное определение размера результата. Произведение чисел большей размерности (2/4 байта) выполняется аналогично. Необходимо заменить директивы DB на DW/DD, регистр AL на АХ/ЕАХ, регистр АН на DX/EDX. Более того, в отличие от команды MUL команда IMLJL допускает более гибкое расположение операндов.

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