Turbo-Assembler. Регістри-вказівники (РВ). Директиви визначення даних 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Turbo-Assembler. Регістри-вказівники (РВ). Директиви визначення даних



Л а б о р а т о р н а р о б о т а №1

ВСТУП

 

Незважаючи на те, що наприкінці 90-х років широке розповсюдження знайшли Windows-подібні системи з розвинутим графічним інтерфейсом, у яких системне програмування здійснюється через обробку подій на рівні повідомлень операційної системи, а не через прямий доступ до пристроїв або використання переривань, все ж класичні методи програмування зовнішніх пристроїв з використанням мови низького рівня асемблер і досі мають велике значення при створенні, наприклад, програм низькорівневого системного керування або драйверів зовнішніх пристроїв. Тому базові приклади, наведені у методичному посібнику, написані для роботи під операційною системою MS-DOS, але більшість з них є Windows-сумісними.

При написані посібника для полегшення читання матеріалу автор намагався дотримуватися таких правил:

 

1. Головні тези та формуліровки, а також головні поняття виділені жирним шрифтом, у деяких випадках – виділені жирним шрифтом та підкреслені.

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

3. Крім стандартних контрольних питань посібник містить велику кількість завдань для перевірки глибини засвоєння матеріалу на практиці. Ці завдання розташовані безпосередньо у тексті робіт та виділені сірим кольором. Хоча їх виконання не є обов’язковим, але студентам, які хочуть досконало вивчити та зрозуміти наведений матеріал, бажано виконати ці нескладні тестові завдання.

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

5. Коментарі у прикладах програм написані дрібним курсивом.

6. У тексті посібника коди команд та директиви асемблера виділені жирним шрифтом та написані прописними літери (наприклад, команда ADD, директива ASSUME ).

7. Робочі фрагменти асемблерних програм написані курсивом, прописними літерами. Там, де визначення кодів асемблерних команд не є суттєвим для наведеного приклада, вони замінені крапками.

Матеріал лабораторної роботи №1 спрямований на вивчення загальних основ програмування на асемблері та необхідного для цього програмного забезпечення - трансляторів з мови асемблер (на прикладі програми Turbo-Assembler) та засобів відлагодження асемблерних програм, які призначені для переведення двійкових машинних кодів у відповідні асемблерні команди (на прикладі програм AFD та Turbo-Debugger) [1,4,8,9].

Матеріал лабораторної роботи №2 спрямований на вивчення асемблерних команд визначення даних, а також арифметичних та логічних операцій мови програмування асемблер [4,7-9].

Матеріал лабораторної роботи №3 спрямований на вивчення команд вітвлення та циклу мови програмування асемблер. Головна мета цієї роботи – навчити студентів писати програми з нетривіальною логікою за запропонованим алгоритмом [4,7-9].

Матеріал лабораторної роботи №4 спрямований на вивчення системи переривань MS-DOS та BIOS та засобів виведення текстової та чисельної інформації на екран монітору через безпосередній доступ до відеопам’яті та через використання апаратних та системних переривань [3-5, 10].

Загальні вимоги для оформлення студентами протоколів лабораторних робіт наведені у додатку 1. Крім того, окремі вимоги до змісту звітів по кожній роботі сформульовані у розділах “ Зміст звіту ” описів цих робіт.

Матеріал лабораторних робіт базується на знанні студентами основ програмування та теорії інформації, особливо таких розділів, як архітектруктура ЕОМ, теорія алгоритмів та системи числення.

Матеріал посібника містить лише одну лабораторну роботу, в якій безпосередньо розглядається робота з зовнішніми пристроями ЕОМ (лабораторна робота №4). Проте велика увага приділяється здійсненню арифметичних та логічних операцій над чисельними даними (у лабораторній роботі №2) та побудові алгоритму поставленої задачі (у лабораторній роботі №3). За думкою автора ці питання є найважливішими при постановці будь-якої задачі програмування зовнішніх пристроїв з метою організації їх роботи за заданим алгоритмом, але нажаль саме на них не звертається необхідної уваги в учбовій літературі по програмуванню.

Слід відзначити також, що питання програмування стандартних зовнішніх пристроїв ЕОМ (монітору, клавіатури, дисководів тощо) через використання переривань MS-DOS та BIOS або шляхом безпосереднього доступу до них, досить вдало розглянуті у довідниковій літературі, яка була опублікована на початку 90-х років [3-5, 8-10]. Всі ці книжки одразу ж після опублікування знайшли великий попит і стали “бестселерами”, їх навіть сьогодні називають “настільними книгами програмістів”. Дуже рекомендую всім студентам звернутися до них! Ви знайдете там багато цікавого та корисного матеріалу, який допоможе Вам не тільки досконало вивчити комп’ютер як складну апаратно-програмну систему, але й найголовніше навчитися писати ефективні та елегантні програми для керування зовнішніми комп’ютерними пристроями. Оскільки з кожним роком з’являються нові апаратні засоби персональних комп’ютерів, а старі суттєво модернізуються та удосконалюються, для роботи на сучасному рівні необхідно звертатися і до теперішніх видань, в яких розглядаються апаратні засоби ЕОМ. Серед таких книжок можна порадити монографію-довідник [11].

Всі наведені у посібнику прикладу програм орієнтовані на систему команд мікропроцесора Intel 8086, який був створений на початку 80-х років і став базовим процесором персональних комп’ютерів типу IBM PC XT і “засновником” родини мікропроцесорів 80х86 фірми Іntel. Незважаючи на те, що мова мікропроцесорів 80386 та і486 є більш вдосконаленою і містить складні операції для обробки чисел з плавоючою комою, всі елементарні математичні функції, додоткові можливості по адресації пам’яті тощо, класичний підхід з орієнтацією на програмування 16-розрядного процесора Intel 8086 за думкою автора має певні переваги. По-перше, всі робочі програми, що написані для цього процесора, можуть працювати без будь-яких змін і на процесорах старших поколінь. По-друге, мова асемблера процесора Intel 8086 не перевантажена великою кількістю команд, що робить її простою для вивчення та розуміння [3-5]. І в решті решт, глибоке знання архітектури та основ програмування мікропроцесора Intel 8086 полегшає вивчення системи команд процесорів старших поколінь фірми Intel. Для студентів, які досконало вивчили мову асемблера процесора Intel 8086 і мають бажання познайомитись з програмуванням процесорів старших поколінь, автор може порекомендувати монографії та учбові посібники [2,6,12].

Невеликий обсяг курсу (один семемтр) не дозволів автору розглянути на практиці всі тонкощі такої різноманітної та багатограної мови програмування, як асемблер. Наприклад, зовсім не розглянуті макрокоманди. Такі важливі аспекти програмування, як виклик процедур та операції зі стеком не виділені у окремі розділи лабораторних робіт, хоча на них і загострюється увага. Майже не розглядаються арифметичні операції над числами подвійної довжини та над числами з фіксованою та плавоючою комою. Всі ці питання теж досить досканало розглянуті в учбовій літературі [1,3].

Треба відзначити, що автор намагався при складанні посібника дотримуватися органічної цільності усього циклу лабораторних робіт. Так, дані, отримані як результати розрахунків у лабораторній роботі № 2 використовуються як початкові для третьої роботи, де реалізуються більш складні алгоритми вітвлень та циклів, а остаточний результат виводиться на екран монітору через безпосередній доступ до відеопам’яті або через систему переривань (робота №4). Така суцільність, на думку автора, не тільки розвиває у студента вміння створювати складні програмні системи через написання та відлагодження їх простих фрагментів, але й взагалі формує системний погляд на світ та його складові частини, впливаючи на розвиток майбутнього інженера та вченого як особистості. Зрозуміло, для цього не достатньо чотирьох лабораторних робіт односеместрового курсу, навіть якщо студент скрупульозно виконував всі завдання для перевірки і відповів на всі контрольні питання. Якщо Вам дійсно сподобалось системне програмування – звертайтеся до книжок та науково-технічних журналів, поповнюйте та поглиблюйте свої знання, ще і ще раз пробуйте програмувати самі. Якщо ви будете наполегливі та працьовиті – до Вас обов’язково прийде вдача, і Ви відчуєте справжнє задоволення, коли зрозумієте, як за допомогою кількох десятків чи сотен програмних рядків можна “підкорити” навіть таку складну і досконалу систему, як комп’ютер, заставляючи його коректно працювати. І це буде не якесь тимчасове задоволення – а дійсна радість від дотику до найновітніших та найглибших досягнень сучасної світової культури та технічних знань людства.

Нажаль, часто-густо в учбовій літературі [3,4,7,8] зустрічаються прикрі помилки у текстах асемблерних програм. Деякі з них були знайдені та виправлені автором при підготуванні методичних вказівок. Всі наведені у посібнику приклади програм були відтестовані на протязі двох років при проведенні лабораторних занять зі студентами кафедри “Електронні прилади та пристрої” факультету електроніки НТУУ “КПІ” та зі студентами спеціальності “Інформатика” фізико-технічного факультету.

І в решті решт, хочу виразити подяку професору кафедри “Електронні системи” НТУУ “КПІ” Терещенко Т.О., та своєму другу, доценту кафедри “Інформаційні технології проектування” Лунтовському А.О. за цінні поради, наданий ними учбово-методичний матеріал та за загальну підтримку всієї праці, а також завідуючому кафедри “Електронні прилади та пристрої” професору Денбновецькому С.В. за цінні зауваження по змісту методичних вказівок.

 

Теоретичні відомості

Регістри-вказівники (РВ)

IP (interrupt point) – адреса, за якою на даний час припинено виконання програми, або лічильник команд. Таким чином, повна адреса, за якою розташований код команди, що виконується, може бути записана таким чином: CS:IP.

DI (data interrupt) – відносна адреса, за якою розташована змінна користувача, що використовується програмою на даний час. Таким чином, повна адреса, за якою розташовані дані користувача, може бути записана таким чином: DS:DI. Слід відзначити, що регістр DI використовується також в парі з сегментним регістром ES.

SP (stack pointer)– вказівник стека. Вказує на відносну адресу останньої змінної, що була завантажена до стека. При виконанні команди «вивантажити змінну зі стека» буде вивантажена саме ця змінна.

SI та DI – індексні регістри. Обидва цих регістра можуть бути використані для розширеної адресації та для реалізації арифметичних операцій складання та віднімання. Але головне їх призначення – робота з рядковими даними. При цьому індексний регістр DI пов'язаний з сегментним регістром DS, а індексний регістр SI - з сегментним регістром ES. Більш досконало про операції обробки рядкових даних у мові асемблера можна прочитати в описі лабораторної роботи №4.

Регістри загального призначення (РЗП) та їхні функції

Акумулятор (АХ)

Акумулятор є головним з регістрів загального призначення. Навіть ті команди процесора, які можуть бути виконані за допомогою інших регістрів, при використанні акумулятора виконуються значно швидше. Цей регістр безпосередньо зв'язаний з арифметико-логічним пристроєм (АЛП) мікропроцесора, який реалізує виконання команд програми на апаратному рівні. Як і всі регістри процесора Intel 8086, акумулятор має 16 розрядів і звертатись до нього на програмному рівні можна через абревіатуру АХ. Можна також заносити числа лише до восьми молодших розрядів акумулятора, звертаючись до них через абревіатуру AL, або до восьми старших, звертаючись до них через абревіатуру АН. Таке ж саме правило діє при звертанні до інших регістрів загального призначення, які будуть розглядатися далі.

Головні функції, які виконуються за допомогою акумулятора у мікропроцесорній системі:

· всі арифметичні операції;

· всі логічні операції;

· всі операції введення/виведення даних;

· операції над рядками.

Базовий регістр (BX)

Регістр загального призначення BX є базовим регістром. Це єдиний регістр загального призначення, вміст якого може розглядатися як посилання на відповідну комірку пам'яті при розширеній адресації. Також може бути використаний разом з акумулятором для арифметичних та логічних операцій та проведення обчислень.

Регістр-лічильник (СХ)

Регістр загального призначення СХ – це регістр-лічильник, який є необхідним для керування числом повторень у циклах та при операціях зсування двійкових чисел. Також може бути використаний для арифметичних та логічних операцій та для проведення обчислень.

Регістр даних (DX)

Регістр загального призначення DX – це регістр даних, який застосовується для їх введення та виведення, для обчислень з подвійною точністю, або для операцій над великими числами при недостатній розрядності регістру АХ. Цей регістр також використовується як додатковий при множенні та діленні цілих чисел.

Регістр прапорів, або регістр стану (РС) Дев'ять з 16 біт регістра стану процесора Intel 8086 є активними та визначають стан процесора після виконання останньої команди. Більшість арифметичних та логічних команд, а також команди зрівняння даних змінюють значення прапорів регістра стану. Прапори регістра стану та їх призначення наведені у таблиці 1, а їх побітове розташування у комірках регістра – у таблиці 2:

Таблиця 1. Призначення прапорів регістра стану

Назва прапора Умовне  
п/п Українською мовою Англійською мовою Позна-чення Що визначає
      Прапор пере-повнення Overflow Flag ОF Наявність одиниці у цьому біті регістра стану вказує на переповнення старшого біта числа при виконанні арифметичних команд.
      Вказівник напрямку при виконанні операцій над рядками   Direction Flag DF Визначає направлення пересилання або порівняння рядкових даних. При цьому направлення ліворуч відповідає збільшенню, а праворуч – зменшенню адрес комірок пам'яті. Значення 1 для прапора DF відповідає направленню праворуч.
    Прапор переривань   Interrupt Flag IF Наявність одиниці у цьому біті регістра стану вказує на можливість виконання переривань від зовнішніх пристроїв, які маскуються.
        Прапор знаку Sign Flag SF Визначається знаком останньої арифметичної операції, яка була зроблена процесором (1 – від'ємне число, 0 – додатне число).
        Прапор нуля Zero Flag ZF Визначається результатом останньої арифметичної операції, яка була зроблена процесором. Нульовий результат обумовлює появу одиниці у цьому біті.
        Режим трасування (покрокового виконання програми) Trace Flag TF Наявність одиниці у цьому біті регістра стану забезпечує покрокове виконання завантаженої програми, що дозволяє програмісту аналізувати стан всіх регістрів процесора та комірок пам'яті після виконанні кожної асемблерної команди. Цей режим є дуже важливим при відлагодженні програм, але безпосередньо у програмах загального призначення він практично не використається. Єдиним виключенням є програми-компілятори.
    Зовнішнє перенесення   Auxiliary Flag AF Визначається результатом останньої арифметичної операції, яка була зроблена процесором. Одиниця у цьому біті свідчить про перенесення з 3-го до 4-го біту числа при виконання операцій над 8-бітовими числами. Використовується при виконанні особливих арифметичних перевірок.
    Прапор перенесення   Carry Flag CF Визначається результатом останньої арифметичної операції, яка була зроблена процесором. Одиниця у цьому біті свідчить про перенесення зі старшого восьмого біта при виконанні арифметичних операцій. При виконанні операцій циклічного зсуву до прапора перенесення переходить останній біт числа.
      Контроль парності числа     Parity Flag PF Вказує на парність перших 8 бітів отриманого результату (1-результат є парним, 0 – не парним). Парність у програмуванні та теорії інформації - це кількість одиниць у двійковому числі. Не плутайте цей параметр з визначенням парності у арифметиці! Не плутайте також прапор парності процесора з бітом парності, який використовується для контролю передавання чисельних даних у комп’ютерних системах та мережах.

Завдання для перевірки №1: Порівняйте поняття парності у звичайній та двійковій арифметиці. Наприклад, чи є парним число 3 з точки зору теорії інформації? Наведіть інші приклади парних та непарних чисел.

Таблиця 2. Розташування бітів регістра стану мікропроцесора Intel 8086

Номер біта                                
Прапор * * * * OF DF IF TF SF ZF * AF * PF * CF  

 

* - біт у процесорі Intel 8086 не задіяний.

Порядок виконання роботи

1. Знайти транслятор і файли afd.exe та td.exe.

2. Проаналізувати текст програми lab1.asm, зрозуміти зміст кожної з асемблерних команд. З’ясувати, як будуть змінюватися дані всіх регістрів процесору при виконанні кожної з них. Текст програми повинен мати такий вигляд:

 

text SEGMENT

ORG 100h

begin: MOV ax,20

MOV bx,30

ADD ax,bx

MOV cx,ax

ADD ch,16

RET

text ENDS

END begin

 

2. Сформувати лістинг, об’єктний та виконуваний код для програми lab1.asm; останній записати у файл lab1.com.

3. Запустити програму lab1.com на обробку. Переконайтеся в тому, що вона коректно виконується (комп’ютер не «підвісає»).

4. Завантажити програму lab1.com до відладчика AFD та крок за кроком виконати всі її команди. Після виконання кожної команди аналізувати стан кожного з регістрів процесора.

5. Завантажити програму lab1.com до відладчика TD та крок за кроком виконати всі її команди. Після виконання кожної команди аналізувати стан кожного з регістрів процесора.

Зміст звіту

1. Послідовність дій, які потрібно виконати для компіляції асемблерної програми. Розглянути два випадка: компіляцію com -програми та компіляцію exe -програми.

2. Таблиця з трьох колонок. До першої занести початковий код асемблерної програми файлу lab1.asm, до другої - її машинні коди, а до третьої - стан усіх регістрів процесору після її виконання.

3. Висновки за роботою.

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

1. Узагальнена структура мікропроцесора Intel 8086 та персонального комп’ютера IBM PC.

2. Що таке початкова та об’єктна програма?

3. Структурна схема гіпотетичного мікропроцесора, призначення всіх його регістрів.

4. Основні регістри процесору типа Intel 8086, їх призначення.

5. Сегментація програми. Сегменти коду, даних та стеку. Їх розташування в пам’яті ЕОМ. Директиви мови асемблера SEGMENT та ENDS.

6. Організація стекової пам’яті та її призначення.

7. Регістр стану процесора. Його призначення. Біти регістра стану у процесорі Intel 8086.

8. Режим трасування програми. Як він встановлюється і для чого використовується?

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

10. Чи потрібно аналізувати регістр стану при виконанні команд програми lab1.asm? Чому?

 

Теоретичні відомості

Директиви визначення даних

Для безпосереднього визначення чисельних та рядкових величин, які не змінюються при виконанні програми, у мові асемблер введені директиви визначення даних. Формат директиви визначення даних такий:

[ім’я] D{n} {вираз}

де D{n} - одна з команд визначення даних, які будуть наведені нижче. Ім’я елемента вказувати не обов’язково. Але, оскільки у програмі завжди існують посилання на ті чи інші дані, використання імен для роботи з ними є найбільш зручним. Наприклад:

 

A1 DW 2; Визначити слово (дві комірки пам’яті) та занести до них число 2

A2 DB 5; Визначити байт (одну комірки пам’яті) та занести до неї число5...................................................................................................................................

...................................................................................................................................

MOV AX,A2; Занести число A2 до акумулятору.

MOV CH,A1; Занести число A1 до старших 8 бітів регістра СX

Існує чотири команди визначення даних, які підтримуються в мові асемблер:

DB -визначити байт (одну комірку пам’яті);

DW -визначити слово (дві комірки пам’яті);

DQ -визначити чотири слова (вісім комірок пам’яті);

DT -визначити десять слів (двадцять комірок пам’яті).

Вирази при описуванні даних можуть бути чотирьох типів:

 

1. Вирази-константи. У директивах з виразами-константами чисельні дані задаються безпосередньо, при цьому визначається також їх тип. Подальше у програмі вони можуть бути використані тільки як дані визначеного типу. Крім того, після числа вказується система числення, у якій записано число:

B - двійкова;

Q - вісімкова;

H - шістнадцятирічна;

D - десяткова.

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

A1 DW 2; Визначити слово (дві комірки пам’яті) та занести до них число 2.

A2 DB 15H; Визначити байт (одну комірки пам’яті) та занести до неї

; шістнадцятирічне число 15

B1 DQ 17Q; Визначити чотири слова та занести до них вісімкове число 17.

Завдання для перевірки №1: Переведіть числа, які позначені змінними A2 та B1 у двійкову та у десяткову системи числення.

Слід зазначити, що у мові асемблера процесору Intel 8086 передбачені переміщення та обробку лише даних одного типу. Наприклад, запис:

A2 DB 15H

MOV AX, A2

є невірним, тому що до акумулятору, якій має 16 розрядів, ми намагаємося завантажити восьмирозрядне число (1 байт). Нижче наведено 2 вірних варіанти:

 

A2 DB 15H MOV AL, A2 A2 DW 15H MOV AX, A2

 

2. Невизначені вирази. Якщо комірка пам’яті мусить бути завантажена не з початку роботи програми, а тільки у процесі її роботи, то її перед початком роботи програми треба зарезервувати. Це досягається таким чином:

A1 DW?;

Тоді у будь-якому місті програми можна поставити оператор типу:

MOV A1, АX

Результатом виконання такого оператора буде перенесення даних з акумулятору до комірки пам’яті з ім’ям A1. Як вам відомо, у мовах високого рівню, таких як ПАСКАЛЬ, С або ж Фортран, таке визначення змінних також ефективно використовується, а самі такі змінні називають невизначеними або динамічними.

Завдання для перевірки №2: Пригадайте, як визначаються динамічні змінні у мові програмування ПАСКАЛЬ? В яких випадках вони використовуються?

3. Вирази з визначенням кількох констант. Вираз може містити водночас декілька констант, що розділяються комами. Кількість таких констант обмежується тільки довжиною рядку. Наприклад:

 

A3 DB 10,12,23H,1001B

 

асемблер визначає такі константи у вигляді послідовних суміжних байт. Посилання на ім’я А3 вказує на першу константу, А3+1 - на другу, А3+2 - на третю тощо. Наприклад, команда:

MOV AH,A3+2

заносить до старших восьми розрядів акумулятора шістнадцятирічне число 23.

При роботі з константами такого типу треба мати на увазі, що якщо команда асемблера DB резервує по одному байту для кожного числа, то команда DW – по одному слову (два байти), незалежно від кількості розрядів у числах, що завантажуються. Тому при використанні команди типа

A3 DW 10,12,23H,1001B

посилання на другу константу (число 12) буде здійснюватись через вираз А3+2, а не А3+1, як це було у попередньому прикладі (поясніть чому саме).

У мовах високого рівня таким чином описуються змінні з індексами або масиви.

Завдання для перевірки №3: Скільки констант визначено в наведеному вище операторі DB під назвою А3? Переведіть всі ці числа у двійкову, десяткову та шістнадцятирічну системи числення. Як би ви визначили відповідний масив з ім’ям А3 у мові програмування ПАСКАЛЬ?

Завдання для перевірки №4: Напишіть на мові асемблера фрагмент програми, у якому:

1. Завантажте п’ять чисел: 12,13H,18,70Q,280 під одним ім’ям.

2. Завантажте друге з визначених чисел до регістру АХ, а п’яте до регістра СХ.

Яку з наведених вище команд ви використали для визначення даних і чому?

 

4. Вирази з повторенням змінних. Директиви визначення даних допускають заповнення сусідніх комірок пам’яті однаковими значеннями через дублювання даних. Формат такої директиви має вигляд:

 

[ім’я] D{n} {число повторень} DUP {вираз}

Наприклад:

 

DW 10 DUP(?); десять невизначених слів

DB 5 DUP(14); п’ять байт, в яких містяться числа 0EH

DB 3 DUP(4DUP(8)); дванадцять байт, в яких містяться числа 8H

Завдання для перевірки №5: Наведіть свої приклади виразів з повторенням змінних та поясніть їх викладачеві. Які ви бачите можливості практичного використання виразів з повторенням змінних при написані програм?

Вираз може містити чисельну або символьну константу. Символьні константи беруться у подвійні або одинарні ‘лапки’ та переводяться при обробці програми в коди ASCII (додаток 3). Наприклад:

A1 DB ‘IBM PC AT’

Більш досконало робота з рядковими константами у мові програмування асемблер буде описана у теоретичних відомостях до лабораторної роботи №4.

Команда перенесення даних

У чотирирозрядних та вісьмирозрядних процесорах існувало багато асемблерних кодів для команд перенесення даних [1]. Наприклад, існували окремі команди для перенесення даних з одного регістру процесору до іншого, з комірки пам’яті до регістру та з регістру до комірки пам’яті. Але перехід до шістнадцятирозрядної шини даних дозволив реалізувати один асемблерний код команди MOV для будь-якої операції перенесення даних [4,7-9].

Формат команди:

{позначка} [код команди] [операнд-приймач], [операнд-джерело]

Увага! Розташування в цій команді приймача і джерела даних є стандартним для процесорів фірми Intel.

Використання команди MOV тісно пов’язано з видами адресації, що використовуються в асемблері. Відрізняють п’ять головних видів адресації.

1. Безпосередня адресація. Дані, що завантажуються, містяться безпосередньо у коді команди. Наприклад:

A4 DB?; Зарезервувати комірку для змінної А1

...........................................................................................................

MOV AX,15H; Завантажити до акумулятору число 15H

MOV A4,15H; Завантажити до комірки пам’яті A1 число 15H

2. Неявна адресація. Джерело та приймач інформації записуються у самому коді команди. Це може бути назва регістру або посилання на комірку пам’яті. Наприклад:

A1 DB 100H; Завантажити до комірки пам’яті A1 число 100H

...............................................................................................................

MOV BX,A1; Завантажити до регістру BX вміст комірки A1

MOV AX,BX; Завантажити до регістру AX вміст регістру BX

3. Пряма адресація. Безпосереднє звертання до комірки пам’яті з визначеним номером. Цей вид адресації використовується при системному програмуванні для занесення даних до комірок пам’яті, вміст яких впливає на виконання системних процедур та загалом на представлення інформації в комп’ютері. Наприклад:

MOV [B8000], ‘A’; Завантажити символ А до відеопам’яті

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

4. Посередня адресація. При цьому виді адресації вміст одного регістру або регістрової пари процесору є вказівником на комірку пам’яті, що містить потрібну інформацію або в яку вона мусить бути поміщена. Посилання на поточну комірку пам’яті позначається символом $ (долар). Наприклад:

MOV BX, 100H

МOV CX, [BX]; Завантажити до регістру СХ число з сегменту даних зі зміщенням 100Н

;(повна адреса комірки пам’яті DS:100H)

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

Існують п’ять можливих ситуацій використання команд ADD та SUB, щопов’язані з представленням та розташуванням даних, які представлені у таблиці 12.

Таблиця 12. Команди додавання та віднімання мови АСЕМБЛЕР

Операція Приклади
Додавання/віднімання регістр-регістр. ADD AX,BX SUB CL,DL
Додавання/віднімання регістр-пам’ять. A1 DW 50H A2 DB 10H …………….......................... ADD AX,A1 SUB CL,A2
Додавання/віднімання пам’ять-регістр. A1 DW 50H A2 DB 10H …………….......................... ADD A1,AX SUB A2,CL
Додавання/віднімання регістр-безпосереднє значення. ADD A1,10H SUB A2,8
Додавання/віднімання пам’ять-безпосереднє значення. A1 DW 50H A2 DB 10H …………….......................... ADD A1,5 SUB A2,12H
Додавання/віднімання регістр-безпосереднє значення. ADD A1,10H SUB A2,8
Додавання/віднімання пам’ять-безпосереднє значення. A1 DW 50H A2 DB 10H ………………....................... ADD A1,5 SUB A2,12H

 

Прямої операції «Пам’ять-Пам’ять» мікропроцесори типу Intel 80x86 не підтримують. Тому такі дії потрібно здійснювати через три елементарних операції процесора:

1. Занесення даних з комірки пам’яті №1 до регістру.

2. Виконання операції додавання або віднімання між регістром та коміркою пам’яті №2.

3. Занесення даних з регістру до комірки пам’яті №2.

Наприклад:

A1 DW 50H

A2 DW 10H

................................................

MOV AX,A1

ADD AX,A2

MOV A2,AX

Множення та ділення чисельних даних в мові асемблер здійснюється за допомогою команд MUL та DIV для беззнакових чисел та за допомогою команд IMUL та IDIV для знакових чисел. Контроль над форматом чисел, що обробляються, не може здійснюватись процесором автоматично, тому вибирати для використання ту чи іншу команду повинен сам програміст.

В асемблері мікропроцесора Intel 8086 існують два формати команди множення - множення байта на байт та множення слова на слово. При множенні байта на байт один з множників знаходиться у регістрі AL, а другий - в байті пам’яті або в однобайтовому регістрі. Результат виконання операції множення буде розміщений в регістрі AX.

Наприклад, фрагмент програми, що знаходить куб числа 5, можна записати таким чином:

A1 DB 5H

.........................

MOV AL,A1

MUL A1

MUL A1

При множенні слова на слово один з множників знаходиться у регістрі AX, а другий - в двох байтах пам’яті або в одному з регістрів процесора. Результатом множення в цьому випадку буде подвійне слово. Його молодші розряди будуть розташовані в регістрі AX, а старші - в регістрі DX. Треба мати на увазі, що ця команда ігнорує (затирає) будь-які дані, що містяться в регістрі DX. Наприклад, фрагмент програми, яка підносить число 100H до кубу можна записати так:

 

A1 DW 100H

......................

MOV AX,A1

MUL A1

MUL A1

Таким чином, формат команд множення у мові програмування асемблер такий:

{позначка} [код команди] [операнд]

Операнд команди множення визначає розташування першого множника та його формат (байт або слово). Другий множник, відповідно до логіки роботи команди, мусить бути розташований в акумуляторі.

Завдання для перевірки №6: За якими ознаками процесор визначає, що в першому випадку треба множити байти, а в другому - слова?

Команда множення IMUL працює цілком аналогічним чином, з урахуванням знаку числа. Наприклад:

 

A1 DB 10110111B

...........................................................

MOV AL,5

MUL A1

...........................................................

MOV AL,5

IMUL A1

Оскільки останній біт числа A1 дорівнює одиниці, то в першому випадку воно буде розглядатися як велике додатне, а в другому - як від’ємне число.

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

Команда ділення в асеблері також має два формати: ділення слова на байт та ділення подвійного слова на слово. При діленні слова на байт ділене міститься в регістрі AX, а дільник - у байті пам’яті або в однобайтовому регістрі. При діленні слова на байт результат ділення буде розміщений таким чином: частка - у регістрі AH, а остача - у регістрі AL. При діленні подвійного слова на слово ділене знаходиться в у парі регістрів DX:AX, а дільник - а дільник - в регістрі або в слові пам’яті. Після операції ділення остача завантажується в регістр DX, а частка в регістр AX. Команда DIV використовується для беззнакових, а IDIV -для знакових даних.

Таким чином, формат команд множення мові програмування асемблер повністю відповідає формату команди множення:

{позначка} [код команди] [операнд]

1.4. Команди логічних операцій

Як відомо, логічні операції є важливим елементом в проектуванні цифрових електронних схем. Але двійкова логіка має також багато спільного із логікою програмування. Наприклад, всі арифметичні операції здійснюються на апаратному рівні як послідовність великого числа логічних операцій [1,4]. Крім того, команди логічних операцій знаходять широке використання для моделювання логіки роботи цифрових схем, для здійснення арифметичних операцій з кодами ASCII, для накладення масок (виділення окремих біт числа), а також для організування логіки програми. В мові програмування асемблер підтримується шість головних команд для виконання логічних операцій: AND, OR, XOR, NOT та TEST.

Ці команди обробляють один байт або одне слово в регістрі або в комірці пам’яті. Встановлюють прапори: CF (прапор переносу), OF (прапор переповнення), PF (прапор парності), SF (прапор знака), ZF (прапор нуля). Працюють команди логічних операцій наступним чином:



Поделиться:


Последнее изменение этой страницы: 2016-04-26; просмотров: 272; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.222.111.24 (0.175 с.)