Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Архитектура компьютеров / 6_Доп программы.doc
Скачиваний:
44
Добавлен:
20.03.2015
Размер:
164.35 Кб
Скачать

C10mul endp

; Пример умножения IMUL:

D10 IMUL PROC

MOV AL, BYTE1 ;Байт * байт

IMUL BYTE2 ;произведение в AX

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

IMUL WORD2 ;произвед, в DX:AX

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

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

IMUL WORD1 ;произвед, в DX:AX

RET

D10 IMUL ENDP

CODESG ENDS

END BEGIN

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

Первый пример команды IMUL перемножает 80H (отрицательное число) на 40H (положительное число). Произведение Е000Hполучается в регистре AX. Используя те же данные, команда MUL дает в результате 2000(12810 (80H) * 6410 (40H) = 819210 или 2000H, а команда IMUL дополняет результат знаковыми единицами и получает Е000H), так что можно видеть разницу в использовании команд MUL и IMUL. Команда MUL рассматривает 80H как +128, а команда IMUL - как -128. В результате умножения -128 на +64 получается -8192 или шестнадцатиричное Е000. (Попробуйте преобразовать Е000 в десятичный формат.)

Второй пример команды IMUL перемножает 8000H (отрицательное значение) на 2000Н (положительное значение). Произведение F0000000 получается в регистрах DX:AX и представляет собой отрицательное значение.

Третий пример команды IMUL перед умножением выполняет расширение байта BYTE1 до размеров слова в регистре AX. Так как значения предполагаются знаковые, то в примере используется команда CBW для перевода левого знакового бита в регистр АН:

шестнадцатиричное 80 в регистре AL превращается в FF80 в регистре AX. Поскольку множитель в слове WORD1 имеет также отрицательное значение, то произведение будет положительным. В самом деле, 00400000Н в регистрах DX:AX - такой же результат, как и в случае умножения командой MUL, которая предполагала положительные сомножители.

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

Можно обнаружить это, используя трассировкe примеров.

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

При умножении на степень числа 2 (2,4,8 и т.д.) более эффективен сдвиг влево на требуемое число битов. Сдвиг более чем на 1 требует загрузки счетчика сдвига в регистр CL. В следующих примерах предположим, что множимое находится в регистре AL или AX:

Умножение на 2:

SHL AL,1

Умножение на 8:

MOV CL,3

SHL AX,CL

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

Обычно умножение бывает двух типов: умножение байта на байт и умножение слова на слово. Как было показано, максимальное знаковое значение в слове + 32767. Умножение больших чисел требует выполнения некоторых дополнительных действий. Рассматриваемый подход предполагает умножение каждого слова отдельно и затем сложение полученных результатов.

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

1365

x12

2730

1365

16380

Представим, что Десятичная арифметика может умножать только двузначные числа. Тогда можно умножить 13 и 65 на 12 раздельно:

13 65

x12 x12

26 130

13 65

156 780

Теперь сложим полученные произведения, но поскольку число 13 представляло сотни, то первое произведение в действительности будет 15600:

15600 +780 =16380

Ассемблерная программа использует аналогичную технику, за исключением того, что данные имеют размерность двойных слов (четыре цифры) в шестнадцатеричном формате.

Умножение двойного слова на слово. Процедура E10XMUL на рис. 4.27 умножает двойное слово на слово.

Множимое MULTCND состоит из двух слов, содержащих соответственно 3206Н и 2521Н. Определение данных в виде двух слов (DW) вместо двойного слова (DD) обусловлено необходимостью правильной адресации для команд MOV, пересылающих слова в регистр AX.

Множитель MULTPLR содержит 6400Н.

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

Первая команда MUL перемножает MULTPLR и правое слово поля MULTCND; произведение 0Е80 Е400 записывается в PRODUCT+2 и PRODUCT+4.

Вторая команда MUL перемножает MULTPLR и левое слово поля MULTCND, получая в результате 138А 5800.

Далее выполняется сложение двух произведений следующим образом:

Произведение 1: 0000 0Е80 Е400 Произведение 2: 138А 5800 Результат: 138А 6680 Е400

Так как первая команда ADD может выработать перенос, то второе сложение выполняется командой сложения с переносом ADC (ADd with Carry). В силу обратного представления байтов в словах в процессорах 8086/8088 область PRODUCT в действительности будет содержать значение 8А13 8066 00Е4. Программа предполагает, что первое слово в области PRODUCT имеет начальное значение 0000.

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

Умножение двух двойных слов включает следующие четыре операции умножения:

Множимое Множитель

слово 2 х слово 2

слово 2 х слово 1

слово 1 х слово 2

слово 1 х слово 1

TITLE EXDWMUL - Умножение двойных слов

CODESG SEGMENT PARA 'Code'

ASSUME CS:CODESG,DS:CODESG,SS:CODESG

ORG 100H

BEGIN: JMP SHORT MAIN

MULTCND DW 3206H ;Элементы данных

DW 2521H

MULTPLR DW 6400Н

DW 0A26H

PRODUCT DW 0

DW 0

DW 0

DW 0

MAIN PROC NEAR ;Основная процедура

CALL E10XMUL ;Вызвать 1-е умножение

CALL Z10ZERO ;Очистить произведение

CALL E10XMUL ;Вызвать 2-е умножение

RET

MAIN ENDP

; Умножение дв.слова на слово:

E10XMUL PROC

MOV AX,MULTCND+2 ;Умнож. прав. cл.

MUL MULTPLR ;множимого

MOV PRODUCT+4,AX ;3аписать произв.

MOV PRODUCT+2,DX

MOV AX,MULTCND ;Умножить лев. cл.

MUL MULTPLR ;множимого

ADD PRODUCT+2,AX ;Сложить с полученным ранее

ADC PRODUCT, DX

RET

E10XMUL ENDP

; Перемножение двух двойных слов:

F10XMUL PROC

MOV AX,MULTCND+2 Слово-2 множимого

MUL MULTPLR+2 * слово-2 множителя

MOV PRODUCT+6,AX Сохранить рез.

MOV PRODUCT+4,AX

MOV AX,MULTCND+2 Слово-2 множимого

MUL MULTPLR * слово-1 множителя

ADD PRODUCT+4,AX Сложить с пред.

ADC PRODUCT+6,AX

ADC PRODUCT,00 Прибавить перенос

MOV AX,MULTCND Слово-1 множимого

MUL MULTPLR+2 * Слово-2 множителя

ADC PRODUCT+4,AX Сложить с пред.

ADC PROOUCT+6,DX

ADC PRODUCT,00 Прибавить перенос

MOV AX,MULTCND Слово-1 множимого

MUL MULTPLR * слово-1 множителя

ADD PRODUCT+2,AX Сложить с пред.

ADC PRODUCT, DX,

RET

F10XMUL ENDP

; Очистка области результата:

Z10XMUL PROC

MOV PRODUCT,0000

MOV PRODUCT+2,0000

MOV PRODUCT+4,0000

MOV PRODUCT+6,0000

RET

Z10XMUL ENDP

CODESG ENDS

END BEGIN

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

Каждое произведение в регистровой паре DX:AX складывается с соответствующим словом в окончательном результате. Пример такого умножения приведен в процедуре F10XMUL на рис. 4.27. Множимое MULTCND содержит 3206 2521, множитель MULTPLR -6400 0A26. Результат заносится в область PRODUCT, состоящую из четырех слов.

Хотя логика умножения двойных слов аналогична умножению двойного слова на слово, имеется одна особенность. После пары команд сложения ADD/ADC используется еще одна команда ADC, которая прибавляет 0 к значению в поле PRODUCT. Это необходимо потому, что первая команда ADC сама может вызвать перенос, который последующие команды могут стереть. Поэтому вторая команда ADC прибавит 0, если переноса нет, и прибавит 1, если перенос есть.

Финальная пара команд ADD/ADC не требует дополнительной команды ADC, так как область PRODUCT достаточно велика для генерации окончательного результата и переноса на последнем этапе не будет.

Окончательный результат 138А 687С 8Е5С ССЕ6 получится а поле PRODUCT в обратной последовательности байтов в словах.

СДВИГ РЕГИСТРОВОЙ ПАРЫ EDX:EAX

Следующая подпрограмма может быть полезна для сдвига содержимого регистровой пары EDX:EAX вправо или влево. Можно придумать более эффективный метод, но данный пример представляет общий подход для любого числа циклов (и соответственно сдвигов) в регистре CX. Заметьте, что сдвиг единичного бита за разрядную сетку устанавливает флаг переноса.

Соседние файлы в папке Архитектура компьютеров