Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Основи програмування мовою Асемблер



Програма — послідовність команд, виконання яких при­водить до розв'язання задачі.

Команда визначає операцію, яку має виконати МП з да­ними. Команда містить у явній або неявній формах інфор­мацію про те, де буде розташований результат операції, та про адресу наступної команди. Код команди складається з кількох частин, які називають полями. Склад, призначення і розташування полів називається форматом команди. У за­гальному випадку формат команди містить операційну та адресну частини. Операційна частина містить код операції, наприклад додавання, множення, передавання даних. Адрес­на частина складається з кількох полів і має інформацію про адреси операндів, результати операції та наступні коман­ди. Формат команди, в якому адресна частина складається з двох полів (ознаки адресації та адреси операндів), показано на рис. 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, б комірка пам'яті з адресою 0012 має вміст 110101112- Вміст акумулятора до операції становить 000000002. Після виконання команди значення вмісту комірки пам'яті копіюється в акумуляторі.

Непряма адресація. За такої адресації у форматі команди вказується номер регістра, в якому зберігається адреса комір­ки пам'яті, що містить операнд. Для збереження 16-розряд-ної адреси у 8-розрядиому процесорі 8-розрядні регістри об'єднані у регістрові пари. У першому регістрі регістрової пари зберігається старший байт адреси, а в другому — мо­лодший. Номер регістрової пари, в якій зберігається адреса, є дворозрядним двійковим числом, тому він розміщується в однобайтовій команді разом з кодом операції.

Як приклад виконання команди МП К580ВМ80А непря­мого завантаження в акумулятор вмісту комірки пам'яті з адресою 001216, що зберігається в регістровій парі DE, пока­зано на рис. 1.10

Рис. 1.9. Команда прямого завантаження в акумулятор вмісту комір­ки пам'яті: а — формат команди; б — схема виконання

Команда непрямого завантаження акумулятора є однобайтовою і крім коду операції містить номер 01 регістрової пари DE. Старша частина адреси комірки пам'яті (00) зберігається у регістрі D, а молодша частина (1216) — у регістрі Е.

Вміст регістрової пари передається в регістр адреси МП, внаслідок чого вміст 110101112 комірки з адресою 0012копіюється в акумуляторі.

Безпосередня адресація. У першому байті команди з без­посередньою адресацією розміщується код операції. Значен­ня операндів заносяться у команду під час програмування і знаходяться у другому або другому і третьому байтах.

Цими значеннями зазвичай є деякі константи, заздалегідь відомі програмісту. У процесі виконання програми значення операндів залишаються незмінними, оскільки вони разом з командою розміщуються в постійному запам'ятовувальному пристрої (ПЗП). Використання такого способу не потребує адрес операндів. Як приклад на рис. 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Я ; 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; Прочитано: 5050 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.04 с)...