![]() |
Главная Случайная страница Контакты | Мы поможем в написании вашей работы! | |
|
Програма — послідовність команд, виконання яких приводить до розв'язання задачі.
Команда визначає операцію, яку має виконати МП з даними. Команда містить у явній або неявній формах інформацію про те, де буде розташований результат операції, та про адресу наступної команди. Код команди складається з кількох частин, які називають полями. Склад, призначення і розташування полів називається форматом команди. У загальному випадку формат команди містить операційну та адресну частини. Операційна частина містить код операції, наприклад додавання, множення, передавання даних. Адресна частина складається з кількох полів і має інформацію про адреси операндів, результати операції та наступні команди. Формат команди, в якому адресна частина складається з двох полів (ознаки адресації та адреси операндів), показано на рис. 1.8.
Поле «ознака адресації» визначає спосіб адресації операнда. Біти полів «Ознака адресації» та «Адреси операндів» разом визначають комірки пам'яті, в яких зберігаються операнди.
Розрізняють такі групи команд: 1) команди передавання даних; 2) команди операцій введення-виведення; 3) команди оброблення інформації (арифметичні, логічні, зсуву, порівняння операндів, десяткової корекції); 4) команди керування порядком виконання програми (переходу, викликів підпрограм, повернення з підпрограм, переривань); 5) команди задання режимів роботи МП.
Код операції (т розрядів) | Ознака адресації (k розрядів) | Адреси операндів (п р озрядів) |
Операційна частина
![]() | ![]() |
Рис. 1.8. Формат команди
Загальну кількість бітів у коді команди називають довжиною формату. Кількість двійкових розрядів т у полі «код операції» забезпечує можливість подання всіх операцій, які виконує МП. Якщо МП виконує М різних операцій, то кількість розрядів визначається так:
.
Якщо пам'ять містить S комірок, то потрібна для запису адреси одного операнда кількість розрядів у полі «адреси операндів» становить:
.
Довжина формату команди визначає швидкість виконання команди і залежить від способу адресації операндів. Існують такі способи адресації: пряма, непряма, безпосередня, автоінкрементна (автодекрементна), сторінкова, індексна, відносна.
Пряма адресація. За такої адресації адреса операнда безпосередньо вказана в команді. Як приклад розглянемо команду МП К580ВМ80А (і 8080) прямого завантаження акумулятора вмістом комірки пам'яті, розміщеної за адресою 001216. Формат і схему виконання цієї команди показано на рис. 1.9.
У байті 1 команди (рис. 1.9, а) міститься код операції пересилання даних в акумулятор з комірки пам'яті, а в байтах 2 і 3 — адреса комірки пам'яті. У байті 2 розміщений молодший (1216), а в байті 3 — старший (0016) байти адреси.
На рис. 1.9, б комірка пам'яті з адресою 00121б має вміст 110101112- Вміст акумулятора до операції становить 000000002. Після виконання команди значення вмісту комірки пам'яті копіюється в акумуляторі.
Непряма адресація. За такої адресації у форматі команди вказується номер регістра, в якому зберігається адреса комірки пам'яті, що містить операнд. Для збереження 16-розряд-ної адреси у 8-розрядиому процесорі 8-розрядні регістри об'єднані у регістрові пари. У першому регістрі регістрової пари зберігається старший байт адреси, а в другому — молодший. Номер регістрової пари, в якій зберігається адреса, є дворозрядним двійковим числом, тому він розміщується в однобайтовій команді разом з кодом операції.
Як приклад виконання команди МП К580ВМ80А непрямого завантаження в акумулятор вмісту комірки пам'яті з адресою 001216, що зберігається в регістровій парі DE, показано на рис. 1.10
Рис. 1.9. Команда прямого завантаження в акумулятор вмісту комірки пам'яті: а — формат команди; б — схема виконання
Команда непрямого завантаження акумулятора є однобайтовою і крім коду операції містить номер 01 регістрової пари DE. Старша частина адреси комірки пам'яті (001б) зберігається у регістрі D, а молодша частина (1216) — у регістрі Е.
Вміст регістрової пари передається в регістр адреси МП, внаслідок чого вміст 110101112 комірки з адресою 00121б копіюється в акумуляторі.
Безпосередня адресація. У першому байті команди з безпосередньою адресацією розміщується код операції. Значення операндів заносяться у команду під час програмування і знаходяться у другому або другому і третьому байтах.
Цими значеннями зазвичай є деякі константи, заздалегідь відомі програмісту. У процесі виконання програми значення операндів залишаються незмінними, оскільки вони разом з командою розміщуються в постійному запам'ятовувальному пристрої (ПЗП). Використання такого способу не потребує адрес операндів. Як приклад на рис. 1.11 зображено формат і схему виконання команди безпосереднього завантаження акумулятора значенням 110101112, яке зберігається у другому байті команди. Після виконання команди це число копіюється в акумуляторі. Після кожного чергового звернення до цієї команди в акумулятор записується таке саме число.
Рис. 1.10. Команда непрямого завантаження акумулятора: а — формат команди; б — схема виконання
Рис. 1.11. Команда безпосереднього завантаження акумулятора
Автоінкрементна (автодекрементна) адресація. У процесі автоінкрементної адресації адреса операнда обчислюється так само, як і за непрямої адресації, а потім здійснюється збільшення вмісту регістра: на один — для звернення до наступного байта, на два — для звернення до наступного слова. Розмір операнда визначається кодом операції.
Сторінкова адресація. Під час використання сторінкової адресації пам'ять поділяється на кілька сторінок однакової довжини. Адресація сторінок здійснюється або з програмного лічильника, або з окремого регістра сторінок. Адресація пам'яті всередині сторінок здійснюється адресою, що міститься в команді.
Індексна адресація. Для утворення адреси операнда до значення адресного поля команди додають значення вмісту індексного регістра, яке називають індексом.
Відносна адресація. За відносної адресації адреса операнда визначається додаванням вмісту програмованого лічильника або іншого регістра із зазначеним у команді числом. Вміст програмованого лічильника або іншого регістра називають базовою адресою. Для збереження базових адрес у МП можуть бути передбачені базові регістри або спеціально виділені комірки пам'яті. Тоді в адресному полі команди вказується номер базового регістра.
У МПС використовується програмування мовою Асемблер. Асемблером називається і мова програмування у мнемокодах команд, і спеціальна програма-транслятор, що переводить (транслює) мнемокоди на машинні коди, які зчитуються мікропроцесором з пам'яті програм, дешифруються і викопуються. Процес переведення мнемокодів на машинні коди називають асемблюванням.
Програма на мові Асемблер містить два типи виразів:
• команди, що транслюються на машинні коди;
• директиви, що керують ходом трансляції. Вираз має такий вигляд:
{<мітка>}: <мнемокод> {<операнд>} {,} {< операнд >} {; коментар}.
У фігурних дужках наведено елементи виразу, яких може не бути у деяких командах. Мітка, мнемокод і операнди відокремлюються хоча б одним пробілом або табуляцією. Максимальна довжина рядка становить 132 символи, але найчастіше використовуються рядки з 80 символів, що відповідає довжині екрана.
Прикладами команд мови Асемблер є:
Мітка | Мнемокод | Операнд(и) | Коментар |
MOV | АХ, 0 | Команда, два операнди | |
М1: | ADD | АХ, ВХ | Мітка, команда, два операнди |
DELAY: | MOV | СХ, 1234 | Мітка, команда, два операнди |
Прикладом директиви є:
Мітка | Мнемокод | Операнд(и) | Коментар |
COUNT: | DB | Мітка, команда, один; операнд |
Мітка на мові Асемблер є символічною адресою команди. Мітками позначаються не всі команди, а лише ті, до яких треба виконувати перехід за допомогою команд переходів або викликів підпрограм. У командах переходів або викликів підпрограм позначення мітки використовується як операнд — символічна адреса переходу, наприклад:
Мітка | Мнемокод | Операнд(и) | Коментарі |
JMP | М1 | ; Перехід до команди з ; міткою МІ | |
CALL | DELAY | ; Виклик підпрограми з; міткою DELAY. |
Після мітки ставиться двокрапка. Першим символом у мітці має бути літера або один із спеціальних символів: знак питання «?»; крапка «.»; знак амперсанд «@»; підкреслювання «_»; знак долара «$». Знак питання і крапка можуть займати лише перше місце. Максимальна довжина мітки — 31 символ. Приклади міток: COUNT, PAGE25, $Е10. Рекомендується використовувати описові та смислові мітки. Усі мітки у програмі мають бути унікальними, тобто не може бути кількох команд з однаковими мітками. Крім того, як мітки не можна використовувати зарезервовані асемблером слова, до яких належать коди команд, директиви, імена регістрів. Наприклад, імена АХ, DI та AL є зарезервованими і використовуються лише для зазначення відповідних регістрів.
Мнемокод ідентифікує команду асемблера. Для мнемокодів використовують скорочені або повні англійські слова, які передають значення основної функції команди: ADD — додати, SUB (SUBtract) — відняти, XCHG (eXCHanGe) — поміняти.
Операнди відокремлюються комами. Якщо задано два операнди, то перший з них завжди є приймачем, а другий — джерелом інформації. Команда може містити різну кількість операндів різних типів, наприклад:
Мітка | Мнемокод | Операнд(и) | Коментарі |
RET | ; Повернутися (операнди не; вказані) | ||
INC | СХ | ; Збільшити СХ (один операнд) | |
ADD | АХ, 12Н | ; Додати 12Н до вмісту АХ; (два операнди) | |
MOV | ВХ, [SI] | ; Занести до регістра ВХ число з комірки ; Пам'яті з адресою DS.SI; (два операнди) |
Коментарі ігноруються у процесі трансляції і використовуються для документування та кращого розуміння змісту програми. Коментар завжди починається із символу «;» і може містити будь-які символи. Коментар також може займати увесь рядок або бути розташованим за командою в одному рядку, наприклад:
Мітка | Мнемокод | Операнд(и) | Коментарі |
; Цей рядок є коментарем | |||
ADD | АХ, ВХ | ; Команда і коментар в; одному рядку |
Оскільки коментарі не транслюються на машинні коди, то їхня кількість не впливає на ефективність виконання програми.
Програма мовою Асемблер називається початковою програмою, або початковим програмним модулем. Асемблювання, або переведення початкової програми на машинні коди, виконує програма-траислятор, наприклад TASM.COM. Залежно від установок, які задає користувач, програма переводить початковий модуль в один з двох програмних модулів: командний модуль (файл з розширенням .СОМ) або об'єктний модуль (файл з розширенням .OBJ).
Командний модуль містить машинні коди команд з абсолютними' адресами і виконується МП. Командний модуль доцільно використовувати тоді, коли ємність програми не перевищує розміру одного сегмента (64 Кбайт). Першим оператором командного модуля є директива ORG 100H (ORIGIN — початок), яка розташовує першу команду програми у сегменті кодів зі зміщенням 100//. Закінчуватися програма має або командою RET, або стандартною процедурою коректного виходу до MS DOS:
Мітка | Мнемокод | Операнд(и) | Коментарі |
MOV | AH, ACH | Занести в АН число АСН (значення параметра переривання ІNT 21Н) | |
INT | 21Н | Викликати стандартну; процедуру переривання 21Н -коректного виходу до MS DOS. |
Останнім записом програми має бути директива END.
Об'єктний модуль містить машинні коди команд з відносними адресами. Об'єктний модуль виконується МП після заміни відносних адрес на абсолютні за допомогою програми-укладача, наприклад LINK.EXE, яка генерує модуль з розширенням .ЕХЕ (ЕХЕ-файл або.ЕХЕ-програму); ЕХЕ-файл, на відміну від командного модуля, може перевищувати ємність одного сегмента. Однак у цьому разі обов'язковим є визначення сегментів за допомогою директив асемблера. Закінчується ЕХЕ-файл стандартною процедурою коректного виходу до MS DOS.
Програма-укладач має ще одне призначення. Вона об'єднує об'єктний модуль з бібліотечними модулями або кілька окремих об'єктних модулів об'єднує в один ЕХЕ-файл. Бібліотечними модулями називають об'єктні файли, що містять найпоширеніші підпрограми. Бібліотечні модулі розміщуються у спеціальному системному файлі — бібліотеці (LIBRARY).
Під час асемблювання програма-транслятор генерує лістинг і файл лістингу програми. Лістинг — відображення на дисплеї або папері текстів початкового програмного модуля, програмного модуля (.СОМ або .OBJ) та повідомлень, які вказують на помилки програмування, зумовлені порушенням правил запису виразів, наприклад немає операнда або неправильний мнемокод команди.
Директиви призначені для керування процесом асемблювання і формування лістингу. Вони діють лише у процесі асемблювання програми і не переводяться на машинні коди. Мова Асемблер містить такі основні директиви:
• початок і кінець сегмента SEGMENT та ENDS;
• початок і кінець процедури PROC та ENDP;
• призначення сегментів ASSUME;
• початок ORG;
• розподіл та ініціювання пам'яті DB, DW, DD;
• завершення програми END;
• відзначення LABEL.
Директиви початку і кінця сегмента SEGMENT та ENDS призначені для опису сегментів, які використовує програма. Директиви початку і кінця сегмента використовують разом, наприклад:
Назва | Мнемокод | Операнд |
DATASG | SEGMENT | {<параметри>} |
![]() | Інші команди або директиви сегмента | |
DATASG | ENDS |
Обидві директиви SEGMENT і ENDS повинні мати однакові назви. Директива SEGMENT може містити три типи параметрів: вирівнювання, об'єднання і класу.
Параметр вирівнювання визначає початкову адресу, або межу, сегмента, наприклад:
PAGE р ххх00;
PARA = xxxx0 (межа за замовчуванням);
WORD = xxxxe (парна межа);
BYTE = ххххх,
де х — будь-яка шістнадцяткова цифра; є — парна шістнадцяткова цифра. Якщо немає параметра вирівнювання за замовчуванням, береться параметр PARA, який вказує на те, що сегмент розташовується на початку параграфа, а початкова адреса сегмента є кратною 16. Параграфом називають область пам'яті розміром 16 байт, початкова адреса якої кратна 16, тобто має праворуч чотири нульових розряди.
Параметр об'єднання вказує на спосіб обробки сегмента під час компонування кількох програмних модулів:
NONE: значення за замовчуванням. Сегмент має бути логічно відокремленим від інших сегментів, хоча фізично він може розташовуватися поряд. Передбачається, що сегмент має власну базову адресу;
PUBLIC: усі PUBLIC — сегменти з однаковими назвою і класом завантажуються у суміжні області та мають одну базову адресу;
STACK: призначення аналогічне параметру PUBLIC. У будь-якій програмі має бути визначений принаймні один сегмент STACK. Якщо визначено більше одного стеку, то покажчик стеку SP (Stack Pointer) встановлюється на початок першого стеку;
COMMON: для сегментів COMMON з однаковими назвами та класами встановлюється одна спільна базова адреса. Під час виконання програми здійснюється накладання другого сегмента на перший. Розмір загальної області визначається найдовшим сегментом;
АТ-параграф: цей параметр забезпечує визначення міток та змінних за фіксованими адресами у фіксованих областях пам'яті;
'Клас': цей параметр може мати будь-яку правильну назву, яка розміщується в одинарних лапках. Параметр використовується для обробки сегментів, що мають однакові назви та класи. Типовими є класи 'STACK' та 'CODE', наприклад:
Назва STACKSG | Мнемокод SEGMENT | Операнд PARA STACK 'STACK' |
Якщо програма не повинна об'єднуватися з іншими програмами, параметр об'єднання не вказується.
Директиви початку і кінця процедури PROC та ENDP використовуються для визначення підпрограм у сегменті кодів і мають такий формат:
<Назва> PROC {<тип процедури>}.
Можливі два типи процедур:
• NEAR — процедура знаходиться в тому самому сегменті, що й команди, які її викликають;
• FAR — процедура знаходиться за межами сегмента. За замовчуванням береться тип процедури NEAR. Сегмент кодів може містити кілька процедур. Описання
сегмента кодів, що містить лише одну процедуру, має такий вигляд:
Назва | Мнемокод | Операнд |
Ім'я_сегмента | SEGMENT | PARA |
Ім'я_процедури | PROC | FAR |
RET | ||
Ім'я_процедури | ENDP | |
Ім'я_сегмента | END S |
Ім'я процедури має бути обов'язково і збігатися з іменем у директиві ENDP, яка визначає кінець процедури.
Директива призначення сегментів ASSUME використовується для встановлення відповідності між сегментами та сегментними регістрами і має такий формат:
ASSUME <сегментний регістр>:<ім'я>{,}{...}.
Наприклад, запис SS:ім_стек вказує, що ім'я стеку визначається вмістом регістра . Одна директива ASSUME може призначати до чотирьох сегментних регістрів у будь-якій послідовності, наприклад:
Мнемокод | Операнд(и) |
ASSUME | SS:ім_стек, DS:ім_код, CS: ім_додатковий_дані |
Для скасування будь-якого призначеного раніше у директиві ASSUME сегментного регістра треба використовувати слово NOTHING:
Мнемокод | Операнд(и) |
ASSUME | ES: NOTHING. |
Якщо програма не використовує будь-який сегмент, то відповідний йому операнд можна відпустити або вказати слово NOTHING.
Директива ORG використовується для зміни вмісту програмованого лічильника без команд умовного чи безумовного переходу. Найчастіше цю директиву використовують для встановлення початкової адреси програми, наприклад директива ORG 100H встановлює програмований лічильник на
зміщення 100Н відносно початку сегмента кодів. Операнд зі знаком долара «$» має поточне значення програмованого лічильника, наприклад директива ORG $+10 H збільшує адресу, завантажену у програмований лічильник, на 10H.
Директиви розподілу та ініціювання пам'яті використовуються для визначення вмісту та резервування комірок пам'яті.
Директива має формат:
{ <ім'я> } Dn {кількість повторень DUP }<вираз>,
де мнемокод вказує на довжину даних: DB — байт; DW — слово (два байти); DD — подвійне слово; DQ — чотири слова; DT — десять байтів. Якщо у форматі наявне ім'я, то далі у програмі воно може використовуватися для позначення комірки пам'яті.
<Вираз> у форматі директиви містить одну або кілька констант для задання початкових значень вмісту комірок пам'яті або знак «?» для невизиачеиого значення вмісту. Наприклад, директива
ALPHA DB 34
означає, що комірка пам'яті з іменем ALPHA містить число 34. У ході виконання програми вміст комірки може бути змінений. Директива
BETA DW?
визначає, що комірка з іменем BETA має розрядиість 16, але вміст комірки є невизначеиим. Директива може містити кілька констант, розділених комами і обмежених лише довжиною рядка. Наприклад, вираз
ARRAYDB01, 02, 11,12,21,22
визначає 6 констант у вигляді послідовності суміжних байтів. Посилання на комірку з іменем ARRAY вказує на першу константу (01), з іменем ARRAY + 1 — на другу (02), з іменем ARRAY + 2 — на третю (11) і т. д. Запис MOV AL, ARRAY + 4 завантажує у регістр AL значення 21.
Одна директива може визначити кілька комірок пам'яті. У цьому разі директива має вигляд:
{ <ім'я> } Dn {кількість повторень} DUP <вираз>.
Наприклад, директива, що визначає 5 байт, які містять число 21, записується так:
DB 5 DUP (21)
Директива завершення програми END є останньою у програмі та має такий формат:
END {<стартова адреса>}.
Параметр директиви <стартова адреса> використовують лише для створення ЕХЕ-файлів.
Директива відзначення LABEL призначена для встановлення відповідності між іменем і типом змінних. Вона. має такий формат:
<ім'я> LABEL {<тип>}.
Як тип можна використовувати слова BYTE, WORD, DWORD, що визначають довжину даних: байт, слово або подвійне слово. Директива LABEL перевизначає параметри процедур NEAR або FAR. Наприклад, директива
TOS LABEL WORD
присвоює комірці пам'яті ім'я TOS і зазначає, що її вміст є словом.
Приклади написання простих програм. Прості програми доцільно оформляти у вигляді командних файлів. Першою директивою таких програм є директива ORG 100 H, останньою — END.
Приклад 1.1. Написати програму додавання вмісту двох 8-розрядних комірок пам'яті, що знаходяться в сегменті даних DS зі зміщеннями 1000 Н і 1001 Н. Результат розмістити у комірці пам'яті з адресою DS: 1002 Н.
У цьому прикладі для простоти не будемо враховувати можливість виникнення перенесення. Програма матиме такий вигляд:
Мнемокод | операнд(и) | Коментарі |
ORG | 100Я | ; Початок програми |
MOV | AL, [1000 H] | ; ALDS:[ 1000 H ] |
; Переслати у 8-розрядний регістр AL ; вміст комірки ; пам'яті з адресою DS:[ 1000 H ] | ||
ADD | AL, [1000 H ] | ;AL-AL + DS:[1000 H ] ; Додати до вмісту AL вміст комірки ; DS:[1000 H ] |
MOV | [1002 H ], AL | ; DS:[1002H]AL ; Переслати вміст AL у комірку DS:[1000 H ] |
END | ; Завершення програми |
Зазначимо, що запис MOV AL, [1000 H ] рівнозначний запису MOV AL, AL, DS:[1000 H ], оскільки сегмент DS прийнятий за замовчуванням.
Приклад 1.2. Написати програму, яка забезпечує розподіл вмісту 16-розрядної комірки пам'яті з адресою ES:[2000 H ] на чотири тетради. Тетради мають бути записані у молодші частини чотирьох послідовних 8-розрядних комірок пам'яті, починаючи з адреси DS:1000 H, причому старшу тетраду треба записати у комірку зі старшою адресою.
У цьому прикладі для запису результату краще використовувати непряму адресацію. Програма має такий вигляд:
Мнемокод | Операнд(и) | Коментарі | |
ORG MOV | 100 H AX, ES:[2000 H ] | ; AX ES:[2000 H ] | |
; Переслати вміст 16-розрядної комірки ; ES:[2000 H ] ; у 16-розрядний регістр АХ | |||
MOV | DX, AX | ; DX АХ, зберегти початкове число в DX | |
AND | AX, 000 FH | ; АХАХ л 0000 0000 0000 1111 ; Виділити молодшу тетраду (скинути ; всі розряди ; АХ, крім чотирьох молодших) | |
MOV | SI, 1000Я | ; SІ 1000 Н ; Записати в SI початкову адресу результату | |
MOV | [SI],AL | ; DS:[SI] AL ; Переслати вміст комірки пам'яті з ; адресою DS:SI у молодшу 8-розрядну частину AL регістра АХ | |
MOV | AX, DX | ;AXDX ; Переслати початкове число з DX у АХ | |
AND | AX, 00Р0Я | ; АХАХ л 0000 0000 1111 0000 ; Виділити другу тетраду | |
MOV | CL, 4 | ; Завантажити у CL число розрядів зсуву | |
ROR | AL,CL | ; Циклічний зсув АL на чотири розряди праворуч, ; унаслідок чого виділене чотирирозрядне число ; переміститься в AL | |
INC | SI | ; SI SI + 1 ; Збільшити SI для запису другого числа | |
MOV | [SI],AL | ; DS: [ SI ] AL, запам'ятати другу тетраду у комірці DS: [ SI ] | |
MOV | AX, DX | АХ DX, переслати початкове число з DX у АХ | |
AND | AX, 0F00 H | АХАХ л 0000 1111 0000 0000, ; Виділити третю тетраду | |
INC | SI | ; SI SI + 1, збільшити адресу результату | |
MOV | [SI], AH | ; DS: [ SI ] AH, запам'ятати третю тетраду | |
MOV | AX, DX | ; AXDX, переслати вихідне число з DX у АХ | |
AND | AX, 0F000 H | ; АХ АХ л 1111 0000 0000 0000, ; Виділити четверту тетраду | |
INC | SI | ; Збільшити адресу результату | |
MOV | CL,A | ; Завантажити у CL число розрядів | |
ROR. | AH,CL | ; Циклічний зсув AL на чотири розряди ; праворуч | |
MOV | [SI],AH | ; Запам'ятати четверту тетраду | |
END. | |||
Для зменшення громіздкості програми, її доцільно зводити до однотипних кроків і використовувати циклічні операції. Розглянутий приклад можна спростити, якщо виконати зсув 16-розрядного числа так, щоб тетрада, яка виділяється, завжди була молодшою. Алгоритм такої програми разом з командами зображено на рис. 1.12.
Типові обчислювальні процедури. Алгоритм типової обчислювальної процедури ЯКЩО-ТО-ІНАКШЕ показано на рис. 1.13.
Цю процедуру застосовують тоді, коли треба реалізувати перехід до однієї з двох обчислювальних процедур залежно від умови. Написання програм мовою Асемблер виконуються командами переходів за умовами встановлення (скидання) прапорців.
Приклад 1.3. Написати програму ділення вмісту АХ на вміст BL. Результат помістити у 8-розрядну комірку пам'яті з адресою DS: 1000 H. Остачею від ділення знехтувати. Якщо вміст BL = 0, то ділення не виконувати, на місце результату помістити число 0 FFH.
Програма має такий вигляд:
Мітка | Операнд(и) | Мнемокод | Коментарі |
ORG | 100 H | ||
CMP | BL, 0 | ; Порівняти вміст BL з нулем; ; результат команди впливає на; встановлення прапорця ; нуля Z | |
JZ | M 1 | ; Якщо Z = 1 (BL = 0), то пе-; рехід на мітку М 1, | |
DIV | BL | ; інакше виконати ділення AL ;AX:BL, ; остача АН | |
JMP | M 2 | ; Безумовний перехід на мітку ; М2 | |
M 1 | MOV | AL, 0FF H | ; Занести число 0FF H у AL |
M 2 | MOV | [1000 H ], AL | Запам'ятати результат у комірці DS: [1000 H ] |
END. |
Процедура ЯКЩО-ТО (рис. 1.14) є частковим випадком процедури ЯКЩО-ТО-ІНАКШЕ і використовується тоді, коли треба реалізувати одну обчислювальну процедуру залежно від умови.
Процедуру РОБИ-ПОКИ (рис. 1.15) використовують для повторення однотипних дій до моменту виконання умови закінчення циклу.
Приклад 1.4. Написати програму додавання за модулем 256 масиву з 100 H байт, розміщених за початковою адресою 7000 H:3000 H.
Результат у вигляді одного байта записати у комірку з адресою 7000Я:5000Я.
Програма має такий вигляд:
Мітка | Мнемокод | Операнд(и) | Коментарі |
ORG | 100 H | ; Початок | |
MOV | АХ, 7000Н | ; Завантажити в АХ адресу сегмента | |
MOV | DS, АХ | ; Завантажити в DS адресу сегмента | |
MOV | SI, 3000 H | ; Завантажити в SI ; зміщення першого ; елемента масиву | |
MOV | CX, 101 H | ;Завантажити у лічильник СХ ; довжину масиву +1 | |
MOV | AL, [SI] | ; Завантажити у AL ; перший елемент масиву | |
M 1 | LOOP | M 0 | Зменшити вміст СХ на 1, якщо СХ ≠ 0, то перейти на мітку M 0, |
MOV | [5000 H ], AL | інакше запам'ятати результат у DS:[5000 H ] | |
JMP | EXIT | вихід | |
M 0 | INC | SI | SI SI + 1 — адреса наступного елемента |
ADD | AL, [SI] | Додати вміст DS.SI до попередньої суми в акумулятори AL | |
JMP | M 1 | Перейти на мітку М 1 для перевірки умови виходу з циклу | |
END. |
Процедура ПОВТОРЮЙ-ДО-ТОГО-ЯК (рис. 1.16) аналогічна попередній, але однотипні дії виконуються перед перевіркою умови.
Рисунок 1.16.
Програма виконання завдання прикладу 1.4 згідно з алгоритмом (1.21) має такий вигляд:
Мітка | Мнемокод | Операнд(и) | Коментарі |
ORG | 100 Н | ; Початок | |
MOV | AX, 7000 H | ; Завантажити в АХ адресу сегмен-; та | |
MOV | DS,AX | ; Завантажити в DS адресу сегмента | |
MOV | SI, 3000 H | ; Завантажити в SI зміщення першого , елемента масиву | |
MOV | CX, 100 H | ; Завантажити в лічильник СХ довжину масиву +1 | |
MOV | AL, [ SI ] | Завантажити в AL перший елемент масиву | |
M 0 | INC | SI | SI SI +1 — адреса наступного елемента |
ADD | AL,[ S ] | Додати вміст DS.SI до попередньої суми в AL | |
LOOP | M 0 | Зменшити вміст СХ на одиницю, якщо СХ≠ 0, то перейти до мітки М 0, | |
MOV | [5000 H ], AL | інакше запам'ятати результат у DS: [5000 H ] | |
JMP | EXIT | вихід | |
END. |
Написання EXE -програм. Написання EХЕ -програм має виконуватися за таких умов:
• зазначення відповідності між сегментами та сегментними регістрами;
• зберігання вмісту DS у стеку;
• записування числа 0 у стек;
• завантаження адреси сегмента даних у регістр DS. Перша вимога виконується за допомогою директиви ASSUME, інші — за допомогою відповідних команд асемблера.
Приклад 1.5. Написати ЕХЕ-програму знаходження максимального числа у масиві 8-розрядних беззнакових чисел. Результат записати в регістр DL.
Програма має такий вигляд:
Мітка (або ім'я) | Мнемокод | Операнд(и) | Коментарі | |||
DATASG | SEGMENT | PARA 'DATA' | ; Визначити сегмент даних | |||
MASSIV | DB | 01,02,03,45, 56,67,78,89, 0FE,10 | ; Визначити у сегменті; даних 10 значень масиву; з іменем MASSIV | |||
DATASG | ENDS | |||||
STACKSG | SEGMENT | PARA STACK 'Stack' | ; Визначити сегмент стеку | |||
DW | 100 DUP (?) | ; Визначити 100 слів | ||||
TOS | LABEL | WORD | ; Визначити ім'я і формат ; Вершини стеку | |||
STACKSG | ENDS | |||||
CODESG | SEGMENT | PARA 'CODE' | Визначити сегмент кодів | |||
BEGIN | PROC FAR | Початок процедури | ||||
ASSUME | SS: STACKSG, DS.DATASG, CS: CODESG | |||||
PUSH | DS | Завантажити вміст DS у стек | ||||
SUB | AX, AX | Встановити нульовий вміст У АХ | ||||
PUSH | AX | Записати нуль у стек | ||||
MOV | AX, DATASG | Завантажити адресу DATASG У АХ | ||||
MOV | DS, AX | Записати адресу DATASG у регістр DS | ||||
LEA | BX, MASSIV | Завантажити у регістр ВХ адресу першого елемента масиву | ||||
MOV | СХ, 10 | Завантажити у СХ довжину масиву | ||||
MOV | DL, [ BX ] | DLDS: [ BX ] | ||||
СОМР: | MOV | AL, [ BX ] | ALDS: [ BX ] | |||
CMP | AL,[ BX+ 1] | Порівняти два сусідніх елементи масиву | ||||
JAE | NEXT | Якщо вміст попереднього елемента масиву [ ВХ ] більший або дорівнює вмісту наступного [BX +1], то перейти ; на мітку NEXT, | ||||
MOV | DL, [ BX+ 1] | ; інакше завантажити у DL; значення [ ВХ + 1] | ||||
NEXT: | INC | BX | ; збільшити ВХ для адресації наступного елемента масиву | |||
LOOP | COMP | ; перевірка умови виходу з; циклу | ||||
RET | ; повернення | |||||
BEGIN | ENDP | ; кінець процедури BEGIN | ||||
CODESG | ENDS | ; кінець сегмента кодів | ||||
END. | і | кінець програми | ||||
У розглянутому прикладі вихід у MS DOS здійснюється командою ЛІТ з використанням для цього адреси, записаної у стек на початку програми командою PUSH DS. Інакше можна завершити програму командою INT 20#.
Контрольні запитання
1. Назвіть складові МПК.
2. За якими класифікаційними ознаками поділяють МП і МПК?
3. На розв'язання яких задач орієнтовані спеціалізовані МП?
4. Які переваги і недоліки мають секційні МП порівняно з однокристальними?
5. Яке призначення та які складові системної шини?
6. Назвіть принципи передавання інформації по шинах — адреси, даних, керування.
7. Назвіть принципи побудови МПС і схарактеризуйте їх.
8. Наведіть типову структуру МПС і поясніть призначення функціональних модулів.
9. Поясніть призначення входу керування третім станом.
10. Дайте визначення архітектури МП.
11. Яка відмінність між гарвардською і фоннейманівською архітектурами?
12. Які функції виконує пристрій керування?
13. Що визначає вміст лічильника команд та як він змінюється?
14. Чим відрізняється акумулятор від інших регістрів МП?
15. Які основні характеристики та структурні схеми процесорів з фоннейманівською і гарвардською архітектурою?
16. Яке призначення регістрів МП з фоннейманівською архітектурою?
17. Схарактеризуйте функції пристрою керування.
18. Наведіть визначення та призначення акумулятора.
19. Поясніть роботу програмованого лічильника.
20. Укажіть місцезнаходження операнда з прямою адресацією.
21. Як визначити адресу операнда з непрямою адресацією?
22. Як визначити значення операнда з безпосередньою адресацією?
23. Як визначити адресу операнда з відносною адресацією?
24. Напишіть програму пересилання вмісту 8-розрядної комірки пам'яті з адресою 7000Я:1000Я у 8-розрядний регістр AL.
25. Напишіть програму віднімання вмісту двох послідовних комірок пам'яті з адресами DS: 35 A 0 H і 35 A 1 H із записом результату в комірку з адресою 35 A 2 H.
26. Напишіть програму додавання масивів байтів з адресами 8350:4735 H і 3660:2200 H за правилом „перший з першим, другий з другим і т.д.”. Занести в масив 6250:2400 Н адреси тих пар доданків, сума яких дорівнює нулю. Довжина масиву 100 Н.
27. Виконайте ділення масиву з 25 Н слів 5 В 00:3000 Н на масив з 25 Н байт 5С00:4000 Н за правилом «перший на перший, другий на другий і т.д.». Результати занести в масив 6000:5000 Н. За потреби ділення на 0 ділення не проводити, а байти результату завантажити числом 1 АН.
Дата публикования: 2014-12-11; Прочитано: 5145 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!