Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ОТ МП.doc
Скачиваний:
187
Добавлен:
10.02.2016
Размер:
5.13 Mб
Скачать

9.4 Створення програм на мові Асемблер-86

9.4.1 Лінійні програми

Вхідний контроль:

  1. Які ділянки програм називаються лінійними?

  2. Команда з якою адресою буде виконуватись після команди

7000:0100 MOV AX,7000H;?

У сучасних додатках рідко використовується програмне забезпечення, цілком написане мовою Асемблера. Частіше мова Асемблера використовується разом з мовою високого рівня, наприклад, С/С++. Частина програми, написана мовою Асемблера, зазвичай призначена для керування периферійними пристроями, оскільки рішення таких задач на мовах високого рівня є більш складним і менш ефективним. Крім того, програми на мові Асемблер виконуються значно швидше, ніж написані будь-якою мовою високого рівня.

Основним принципом отримання ефективних програм є ефективний розподіл та використання ресурсів процесора. Оптимізація програми реалізується за рахунок мінімізації пересилань, використання вказівників на дані замість самих даних при роботі зі складними структурами, розміщення структури даних в одній локальній області пам'яті, розподіл регістрів для локальної ділянки програми тощо. Так, перш за все розподіляються спеціалізовані регістри, а решта виділяється для зберігання найбільш часто використовуваних даних. Дані, які використовуються одноразово, слід зберігати у пам’яті. Акумулятор виділяється для зберігання оперативних результатів.

Потрібна міра оптимальності програми визначається умовами її експлуатації і залежить від багатьох факторів. Для рідко використовуваних програм високий рівень оптимізації не є обов’язковий. Простіше за все оптимізація програми реалізується на лінійних послідовностях команд. У середині лінійних ділянок робиться присвоювання, виконуються операції над даними, вилучаються зайві операції за рахунок одноразового програмування загальних виразів з подальшим включенням їх у циклічні програми. Більш складною задачею є виконання еквівалентних адекватних перетворювань на лінійних ділянках з метою спрощення аналітичних виразів при збереженні достатньої точності та надійності обчислень.

Приклад 9.4.1Ввести з портів з адресами 3F8Hта 2F8Hдані та запам’ятати їх у суміжних комірках пам’яті, починаючи з адреси 0020Н у сегменті даних. Округлити їх до 4-х розрядів, упакувати в один байт і зберегти у пам’яті за адресою 0030Ну сегменті даних.

Під упакуванням розуміють розміщення у старшому півбайті першого числа, а в молодшому півбайті – другого числа.

Задача вирішується за виконанням наступного фрагмента програми:

MOV DX,3F8H ; Завантаження у регістр DX адреси порту 3F8H

MOV SI,0020H ; Завантаження в індексний регістр SI адреси комірки

; пам’яті для першого даного

MOV DI,0030H ; Завантаження у індексний регістр DI адреси комірки

; пам’яті для упакованого даного

MOV CL,04H ; Завантаження у CL кількості операції зсувів

XOR СН,СН ; Обнулення регістра СН

IN AL,DX ; Введення в акумулятор першого даного з порту

MOV CH,AL ; Запам’ятовування першого даного у регістрі СН

MOV [SI],AL ; Запам’ятовування першого даного у пам’яті

MOV DX,2F8H ; Завантаження у регістр DX адреси порту 2F8H

IN AL,DX ; Введення в акумулятор другого даного з порту

INC SI ; Нарощування адреси комірки пам’яті для другого

; даного

MOV [SI],AL ; Запам’ятовування другого даного у пам’яті

AND CH,F0H ; Округлення першого даного

AND AL,F0H ; Округлення другого даного

SHR AL,CL ; Переміщення округленого другого даного на місце

; другого півбайта

OR CH,AL ; Упаковування даних в один байт

MOV [DI],CH ; Запам’ятовування упакованих даних

NOP

Припустимо, що перше дане D1 становить 12Н(00010010В), а другеD2 – 34Н(00110100В). Округлення першого даного дасть півбайт, який дорівнює 0001В, а другого – 0011В. Упаковане дане складатиме 00010011Вабо 13Н.

Програма складена з урахуванням подальшої можливості введення із портів масивів даних, їх упакування та запам’ятовування.

Приклад 9.4.2Число -28Нзаписати у регістриDLтау прямому коді двома способами. Наступні фрагменти програми виконують ці записи:

а) MOV DL,-28H б) MOV DH,-28H

NEG DL NOT DН

OR DL,80H ADD DН,81H

Запис будь-якого від’ємного числа здійснюється у регістр у доповнювальному коді, тобто у регістрах DLтаDHпісля виконання перших двох команд буде записане число -28Ну доповнювальному коді, тобто числоD8H. Для подання цього даного у прямому коді можна використати командуNEG DL, яка подасть це число без знака, а саме 28Н, та командуOR DL,80H, яка установить 1 у старшому розряді. В результаті отримаємо прямий код числа -28Н, який дорівнюєА8Н(фрагмент а)). У фрагменті б) числоD8H, записане у регістру доповнювальному коді, інвертується і до нього додається число 81Н. Ця операція установлює 1 у старшому розряді результату і додає 1 до молодшого розряду; у регістріDLбуде записане також числоА8Н.

Приклад 9.4.3Охарактеризувати ознакамиZF, SFтаPFдане, яке зберігається у регістріAL. Команда

OR AL,AL

не змінює дане, яке зберігається в AL, і виставляє зазначені ознаки. У припущенні, що дане є число 56Н, ознаки дорівнюватимуть:

ZF=0;

SF=0;

PF=1.

Приклад 9.4.4 Знайти вміст акумулятора та ознак CF, SF, AF після виконання фрагментів програм:

а) MOV AL,EH б) MOV AL,2AH в) MOV AL,2AH

SUВ AL,2AH SUB AL,4EH SUB AL,E4H

NOP NOP NOP

При виконанні віднімання отримуємо вміст акумулятора:

а) _4EH б) _2AH в) _2AH

2AH 4EH E4H

24H DCH 46H

CF=0 CF=1 CF=1

AF=0 AF=1 AF=0

SF=0 SF=1 SF=0

Ознака CFустановлюється в 1, якщо мала місце позика, тобто у фрагментах б) та в). При відніманні із меншого числа більшого ознакаCFзавжди установлюється в 1, а ознака знакуSF=1 тільки у разі отримання “коректного” результату, тобто за відсутності переповнення розрядної сітки. Для виявлення меншого з двох чисел слід користуватися ознакоюCF, якщо аналізується результат виконання команд віднімання або порівняння.

Приклад 9.4.5При завантаженні комп’ютера тестуються наявні асинхронні адаптери й ініціалізуються перші два з них:СОМ1 таСОМ2, які мають базові адреси 0000:0400Нта 0000:0300Н. Наступний фрагмент програми дозволяє прочитати з регістра керування з адресою 3FBH портуСОМ1 байт стану режиму адаптера:

MOV DX,3FBH ; Завантаження адреси керувального регістра у DX

IN AL,DX ; Введення поточного режиму адаптера

При правильній ініціалізації байт стану дорівнюватиме 000Х0011В= 03Набо 13Н. Це відповідає такому режиму: немає контролю на парність (D3 = 0,D4 =X), один стоповий біт (D2 = 0), кількість бітів дорівнює 8 (D1 = 1,D2 = 1).

Приклад 9.4.6Два байтиD1 таD2 є 3- та 5-м елементами масиву, що починається з ефективної адреси 0010Н. Інвертувати перший байт, вирізати 0, 2, 7 розряди другого; отримані результати зберегти у стеку. Припустимо, що перший байтD1 дорівнює 25Н, а другийD2 – 73Н. Виконаємо вказані операції порозрядно та вкажемо ознаки результату (прапорці) на кожному кроці виконання. Сегменти стека та даних є суміщені.

F1=11011010 =DAH.

F2 = D2 /\ mask; mask = 01111010 = 7АH.

Задамо довільно 16 елементів масиву байтів, з яких третій дорівнює 25Н, а п’ятий дорівнює 73Н.

7000:0010 12 34 56 25 43 73 43 54 65 76 82 37 15 13 14 61 52.

Вказівник стека задамо таким, який дорівнює 2080Н.

Структурна схема програми наведена на рис. 9.12.

Фрагмент програми, яка вирішує цю задачу, має вид

MOV AX,7000H ; Завантаження

MOV DS,AX ; сегментних

MOV SS,AX ; регістрів

MOV SP,2080H ; Завантаження вказівника стека

MOV BX,0010H ; Завантаження базового регістра

MOV AL,[BX+03] ; Пересилання першого байта до AL

NOT AL ; Інвертування першого байта

MOV AH,[BX+05] ; Пересилання другого байта до АН

AND AH,7AH ; Змінення другого байта

PUSH AX ; Запам’ятовування результатів у стеку

Рисунок 9.12 – Структурна схема програми

Програма виконується так.

Усі команди пересилань та команда NOTне змінюють прапорці; результатом виконання командиNOTє числоDAH, що вміщується у регістріAL, а результатом командиANDє число 72Н, що вміщується вАН; ця команда установлює прапорціOF= 0,CF= 0,SF= 0,AF= 0,ZF= 0,PF= 1.

Приклад 9.4.7Виконати операцію виключного АБО над двома словами,D1 таD2, що розміщені у пам’яті. Помножити результат на беззнакове число 33Н і розташувати добуток на місці другого слова. Перше знаходиться у масиві, що починається зі зміщення 10Нта адресоване вмістом індексного регістраSI, а друге знаходиться у масиві, що починається зі зміщення 20Нта адресується вмістом індексного регістраDIі зміщенням 2Н. Початкова адреса сегмента даних є 7000Н.

Створимо два масиви, починаючи зі зміщення 10Нта 20Нвідповідно. Припустимо, що у регістріSIміститься число 6Н, а у регістріDI– число 2Н.

7000:0010 12 34 56 25 40 43 71 43 65 76 82 37 15 13 18 60

7000:0020 14 36 58 27 45 73 48 54 65 76 82 39 17 15 14 61

Тоді перше слово D1 становить 4371Н, а другеD2 дорівнює 7345Н. Перший проміжний результатF1 становить:

F1=D1D2=3034Н.

Ознаки результату становлять OF= 0,CF= 0,SF= 0,AF= 0,ZF= 0,PF= 0.

Другий результат F2 становить:

F2 =F133H= 3034H33H= 99А5СН.

Ознаки результату дорівнюють: OF= 1,CF= 1,SF= 1,AF= 1,ZF= 0.

Програма має вигляд:

MOV AX,7000H ; Організація

MOV DS,AX ; сегмента даних

MOV BX,0010H ; Завантаження до ВХ початкової адреси першого

; масиву

MOV DI,2H ; Завантаження

MOV SI,6H ; індексних регістрів

XOR DX,DX ; Обнулення DX

MOV AX,[BX+SI] ; Завантаження першого слова до АХ

MOV BX,0020H ; Завантаження до ВХ початкової адреси другого

; масиву

XOR AX,[BX+DI+2] ; Складання за модулем 2 з другим словом

MOV CХ,33H ; Завантаження множника до CL

MUL CХ ; Множення на константу 33Н

MOV [BX+DI+2],AX ; Пересилання молодшого слова добутку на місце

; другого слова

MOV [BX+DI+4],DX ; Пересилання старшого слова добутку до другого

; масиву

Після виконання програми в регістр АХбуде записане число 9А5СН, а в регістрDX –число 0009Н.

Контрольні питання:

  1. Як подаються числа беззнакові та зі знаком у МП сім’ї Intel?

  2. Подані в яких системах числення дані можуть оброблюватись у МП сім’ї Intel?

  3. Четвертий елемент першого масиву дорівнює 32Н. Поділити його на п’ятий елемент другого масиву, що дорівнює 4Н, усіма відомими вам способами.

  4. Інвертувати слово, що становить п’ятий елемент першого масиву; поділити результат на третій елемент другого масиву. Частку разом з регістром прапорців запам’ятати у стеку.

  5. Знайти логічний добуток четвертого байта першого масиву та третього байта другого масиву. Результат помножити на 44Н, добуток запам’ятати за ефективною адресою, що визначається вмістом регістраDI.

  6. Заповнити масив з чотирьох слів, починаючи з адреси DS:50, використовуючи командуSTOSW.

  7. Порівняти нульовий елемент першого масиву з другим елементом другого масиву. Запам’ятати у стеку вміст регістра прапорців та суму вказаних елементів.

Контрольні питання підвищеної складності:

    1. Завантажити одночасно регістр сегмента даних та акумулятор двобайтовими елементами першого масиву, починаючи з другого елемента за допомогою прямого адресування.

    2. Сумістити сегмент даних та додатковий сегмент даних.