Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lekz._9.doc
Скачиваний:
3
Добавлен:
05.05.2019
Размер:
168.96 Кб
Скачать

1.6. Множення чисел без знака

Для множення чисел без знака призначена команда mul співмножник _1

Як бачите, в команді вказано всього лише один операнд-співмножник_1. Другий операнд - співмножник_2 задано неявно. Його місце розташування фіксоване і залежить від розміру співмножників. Оскільки в загальному випадку результат множення перебільшує будь-який з його співмножників, то його розмір і місце розташування мають бути теж визначені однозначно. Варіанти розмірів співмножників і розміщення другого операнда і результату наведено в табл. 9.1.

Таблиця 9.1 – Розташування операндів і результату при множенні

співмножник _1

співмножник _2

Результат

Байт

al

16 біт в ax: al — молодша частина результату; ah — старша частина результату

Слово

ax

32 біт в парі dx:ax: aх —молодша частина результату; dx — старша частина результату

Подвійне слово

eax

64 біт в парі edx:eax: eax—молодша частина результату; edx — старша частина результату

Лістинг 3. Множення

<1> ;prg_9_3.asm

<2> masm

<3> model small

<4> stack 256

<5> .data ;сегмент даних

<6> rez label word

<7> rez_l db 45

<8> rez_h db 0

<9> .code ;сегмент коду

<10> main: ;точка входу в програму

<11> ...

<12> xor ax,ax

<13> mov al,25

<14> mul rez_l

<15> jnc m1 ;якщо нема переносу, то на m1

<16> mov rez_h,ah ;старшу частину результату

;в rez_h

<17> m1:

<18> mov rez_l,al

<19> exit:

<20> mov ax,4c00h ;стандартний вихід

<21> int 21h

<22> end main ;кінець програми

З таблиці видно, що добуток складається з двох частин і в залежності від розміру операндів розміщується в двох місцях - на місці "співмножник_2" (молодша частина) і в додатковому регістрі ah, dx, edx (старша частина). Як же динамічно (тобто під час виконання програми) дізнатися, що результат достатньо малий і вмістився в одному регістрі або що він перевищив розмірність регістра і старша частина виявилася в іншому регістрі? Для цього залучаються вже відомі нам з попереднього обговорення прапори переносу cf і переповнення of:

• якщо старша частина результату нульова, то після операції множення прапори cf = 0 і of = 0;

• якщо ж ці прапори ненульові, то це означає, що результат вийшов за межі молодшої частини добутку і складається з двох частин, що і потрібно враховувати при подальшій роботі.

Наведемо приклад програми.

У цій програмі у рядку 14 здійснюється множення значення в rez_l на число в регістрі al. Згідно з інформацією в табл. 9.1, результат множення буде розташовуватися в регістрі al (молодша частина) і регістрі ah (частина старша). Для з'ясування розміру результату в рядку 15 командою умовного переходу jnc аналізується стан прапора cf і якщо воно не дорівнює 1, то результат залишився в межах регістра al. Якщо ж cf = 1, то виконується команда в рядку 16, яка формує в полі rez_h старше слово результату. Команда у рядку 18 формує молодшу частину результату. А тепер зверніть увагу на сегмент даних, а саме, на рядок 6. У цьому рядку міститься директива label. Ми ще не раз будемо стикатися з цією директивою. У даному випадку вона призначає ще одне символічне ім'я rez адресі, на яку вже вказує інший ідентифікатор rez_l. Відмінність полягає в типах цих ідентифікаторів - ім'я rez має тип слова, який йому призначається директивою label (ім'я типу зазначено в якості операнда label). Ввівши цю директиву в програмі, ми підготувалися до того, що, можливо, результат операції множення буде займати слово в пам'яті. Зверніть увагу, що ми не порушили принципи: молодший байт за молодшою адресою. Далі, використовуючи ім'я rez, можна звертатися до значення в цій області як до слова.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]