Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Абель.docx
Скачиваний:
13
Добавлен:
26.11.2018
Размер:
569.84 Кб
Скачать

Imul byte2 ; произведение в aх

MOV AX,WORD1 ;Слово * слово

Imul word2 ; произвед. В dx:ax

MOV AL,BYTE1 ;Байт * слово

CBW ; расшир. множ. в AН

Imul word1 ; произвед. В dx:ax

RET

D10IMUL ENDP

CODESG ENDS

END BEGIN

__________________________________________________________________________

Рис.12.3. Беззнаковое и знаковое умножение.

Второй пример команды MUL генерирует шест.10000000 в регистpах DX:AX.

Третий пример команды MUL выполняет умножение слова на байт и требует

расширение байта BYTE1 до размеров слова. Так как предполагаются

беззнаковые величины, то в примере левый бит регистра AH равен нулю. (При

использовании команды CBW значение левого бита регистpа AL может быть 0

или 1). Произведение - шест.00400000 получается в регистрах DX:AX.

Знаковое умножение: Команда IMUL

----------------------------------

Команда IMUL (Integer MULtiplication - умножение целых чисел)

умножает знаковые числа. На рис.12.3 в процедуре D10IMUL используются те

же три примера умножения, что и в процедуре C10MUL, но вместо команд MUL

записаны команды IMUL.

Первый пример команды IMUL умножает шест.80 (отрицательное число) на

шест.40 (положительное число). Произведение - шест.E000 получается в

регистре AX. Используя те же данные, команда MUL дает в результате

шест.2000, так что можно видеть разницу в использовании команд MUL и IMUL.

Команда MUL рассматривает шест.80 как +128, а команда IMUL - как -128. В

результате умножения -128 на +64 получается -8192 или шест.E000.

(Попробуйте преобразовать шест.Е000 в десятичный формат).

Второй пример команды IMUL умножает шест.8000 (отрицательное

значение) на шест.2000 (положительное значение). Произведение -

шест.F0000000 получается в регистрах DX:AX и представляет собой

oтрицательное значение.

Третий пример команды IMUL перед умножением выполняет расширение

байта BYTE1 до размеров слова в регистре AX. Так как значения

предполагаются знаковые, то в примере используется команда CBW для

перевода левого знакового бита в регистр AH: шест.80 в pегистре AL

превращается в шест.FF80 в регистре AX. Поскольку множитель в слове WORD1

имеет также отрицательное значение, то произведение должно получится

положительное. В самом деле: шест.00400000 в регистрах DX:AX - такой же

результат, как и в случае умножения командой MUL, которая предполагала

положительные сомножители.

Таким образом, если множимое и множитель имеет одинаковый знаковый

бит, то команды MUL и IMUL генерируют одинаковый результат. Но, если

сомножители имеют разные знаковые биты, то команда MUL вырабатывает

положительный результат умножения, а команда IMUL - отрицательный.

Можно обнаружить это, используя отладчик DEBUG для трассировки

примеров.

П о в ы ш е н и е э ф ф е к т и в н о с т и у м н о ж е н и я: При

умножении на степень числа 2 (2,4,8 и т.д.) более эффективным является

сдвиг влево на требуемое число битов. Сдвиг более чем на 1 требует

загрузки величины сдвига в регистр CL. В следующих примерах предположим,

что множимое находится в регистре AL или AX:

Умножение на 2: SHL AL,1

Умножение на 8: MOV CL,3

SHL AX,CL

Многословное умножение

------------------------

Обычно умножение имеет два типа: "байт на байт" и "слово на слово".

Как уже было показано, максимальное знаковое значение в слове ограничено

величиной +32767. Умножение больших чисел требует выполнения некоторых

дополнительных действий. Рассматриваемый подход предполагает умножение

каждого слова отдельно и сложение полученных результатов. Рассмотрим

следующее умножение в десятичном формате:

1365

х12

-----

2730

1365

-----

16380

Представим, что десятичная арифметика может умножать только двузначные

числа. Тогда можно умножить 13 и 65 на 12 раздельно, cледующим образом:

13 65

х12 х12

--- ---

26 130

13 65

--- ---

156 780

Следующим шагом сложим полученные произведения, но поскольку число 13

представляло сотни, то первое произведение в действительности будет 15600:

15600

+780

-----

16380

Ассемблерная программа использует аналогичную технику за исключением

того, что данные имеют размерность слов (четыре цифры) в шестнадцатеричном

формате.

У м н о ж е н и е д в о й н о г о с л о в а н а с л о в о.

Процедура E10XMUL на рис.12.4 умножает двойное слово на слово. Множимое,

MULTCND, состоит из двух слов, содержащих соответственно шест.3206 и

шест.2521. Определение данных в виде двух слов (DW) вместо двойного слова

(DD) обусловлено необходимостью правильной адресации для команд MOV,

пересылающих слова в регистр AX. Множитель MULTPLR содержит шест.6400.

Область для записи произведения, PRODUCT, состоит из трех слов. Первая

команда MUL перемножает MULTPLR и правое cлово поля MULTCND; произведение

- шест.0E80 E400 записывается в PRODUCT+2 и PRODUCT+4. Вторая команда MUL

перемножает MULTPLR и левое слово поля MULTCND, получая в результате шест.