Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
А С Е М Б Л Е Р.doc
Скачиваний:
7
Добавлен:
12.08.2019
Размер:
835.58 Кб
Скачать

20

А С Е М Б Л Е Р

Обробка асемблерних програм

Розглянемо компоненти процесора, які видні програмісту на асемблері.

Одним з найзначніших компонентів процесора є регістри. Процесори 8088, 8086, 80188 і 80186 мають однакові набори регістрів, тому їх всі ми об'єднаємо під терміном «8086». Процесори більш нових моделей лінійки x86 розширюють кількість регістрів, що використовуються, зберігаючи всі регістри попередників для зворотної сумісності.

Розробники фірми Intel розділяють регістри на 3 групи: регістри загального призначення (Рон або робочі регістри), сегментні регістри і спеціальні регістри. Робочі регістри – це регістри, які можуть виступати в ролі операндів арифметичних, логічних і інших інструкцій процесора. Кожний з них грає свою роль в системі, тому можна не погодитися з Intel`овским терміном «регістри загального призначення». Сегментні регістри використовуються для доступу до блоків пам'яті, так званих «сегментів». Спеціальні регістри відображають стан системи, і до них немає прямого доступу.

Регістри загального призначення процесора 8086

Існує вісім 16-бітових робочих регістрів. Це АХ, BX, CX, DX, SI, DI, BP і SP. Будь-які з них можуть бути задіяний в обчислювальному процесі, але необхідно враховувати, що все ж таки багато інструкцій процесора для роботи вимагають використовування строго певних регістрів з цієї групи.

Регістр АХ (Accumulator) доцільно використовувати для тимчасового зберігання даних (наприклад в обчисленнях); BX (Base) – для завдання адрес в пам'яті; CX (Count) – для рахунку (кількість повторів циклу); DX (Data) – для зберігання даних в деяких арифметичних операціях а також адрес для доступу до шини уведення-виведення.

S I (Source Index) і DI (Destination Index) так само мають спеціальне призначення. З їх допомогою можуть задаватися адреси для здійснення непрямого доступу до пам'яті, а також для виконання спеціальних «рядкових інструкцій» процесора 8086.

Регістр BP (Base Pointer) схожий з регістром BX, але в основному використовується для доступу до передаваним через стек параметрів з підпрограми.

Серед всіх регістрів виділяється SP (Stack Pointer), за допомогою якого задається адреса верхівки програмного стека. Це дуже важливо у багатьох випадках, тому строго не рекомендується використовувати SP в іншій ролі.

Окрім 16-бітових регістрів, в процесорі 8086 присутні ще вісім 8-бітових регістрів – AL, AH, BL, BH, CL, CH, DL і DH. Але ці регістри не реалізовані окремо від 16-бітових на фізичному рівні. Кожний з них – це певна частина 16-бітового регістра. Наприклад, AL означає «Ах Low» – молодший байт АХ, а CH – «Cx High» –

старший байт CX. Важливо запам'ятати, що зміна будь-якого з 8-бітових регістрів спричинить за собою зміну і відповідного йому 16-бітового регістра, як і навпаки.

Р егістри спеціального призначення процесора 8086

В процесорі 8086 існує два регістри спеціального призначення – IP (Instruction Pointer) і FLAGS. Процесор особливим чином маніпулює цими регістрами, тому до них немає прямого доступу, як до РЗП або сегментним регістрам.

IP – це 16-бітовий регістр, який використовується для завдання адреси інструкції процесора, яка виконується в даний момент часу.

Регістр FLAGS не схожий на решту регістрів процесора – він не береже числових значень, а є «набором» однобітових значень – прапорців, які характеризують стан процесора. Хоч FLAGS має довжину 16 біт, реально використовуються тільки 9 з них. Прапорці, що часто використовуються, – zero (нуль), carry (перенесення), sign (знак) і overflow (переповнювання). Це так звані прапорці умови.

Сегменти і сегментні регістри в 8086

Оперативна пам'ять комп'ютера складається з осередків розміром в один байт. Загальна кількість байт =2 в ступені ША. Процесор 8086 16-розрядний, але ША 20-розрядна, т.о. можна адресувати 1 Мбайт пам'яті. Це досягається завдяки сегментації - розбиттям пам'яті на блоки завдовжки в 64 Кілобайти, так звані сегменти. Положення сегменту в пам'яті описується 16-бітовим значенням, яке, для отримання доступу до цього сегменту, повинне зберігатися в одному з сегментних регістрів. А усередині кожного з сегментів дані адресуються через 16- розрядний зсув (offset) щодо початку сегменту.

Існують чотири сегментні регістри - це CS (Code Segment), DS (Data Segment), ES (Extra Segment) і SS (Stack Segment). Всі ці регістри можуть використовуватися для роботи з будь-якими сегментами пам'яті, але є деякі обмеження.

CS повинен бути пов'язаний з сегментом, який береже виконувані в даний момент команди процесора (code). Щоб виконати інструкції, що знаходяться в інших сегментах, просто необхідно змінити вміст CS.

Регістр SS використовується для операцій із стеком програми. Стек працює за принципом FILO (First Input Last Output). Це означає, що при читанні ми забираємо із стека останнє записане в нього дане. В більшості випадків стек використовується для збереження стану процесора (наприклад, вмісту регістрів), передачі параметрів в підпрограми і ін., тому змінювати SS рекомендується тільки в окремих випадках і одночасно з SP.

DS і ES можуть бути пов'язаний з будь-якими сегментами пам'яті, хоча зручніше всього було б DS застосовувати для доступу до даних програми (наприклад, змінним), що часто використовуються, а ES – як додатковий регістр, коли інші сегментні регістри задіяні, і небажано їх зміна.

Хоча, у принципі, сегментні регістри, як і регістри загального призначення, можна використовувати для тимчасового зберігання даних, але у будь-якому випадку навряд чи це буде доброю ідеєю, оскільки будь-яка допущена помилка (наприклад, якщо забути відновити старий вміст регістра) може привести до «зависання» системи.

Регістри процесора 80386

В процесорі 80386 всі регістри загального призначення, а також IP і FLAGS розширилися до 32 біт. Для сумісності з 8086, збереглися 16-бітові регістри, які тепер є молодшими словами розширених регістрів, і доступні під старими іменами. Для доступу до розширених регістрів, додається префікс «E» (Extended). Наприклад, 32-бітовий аналог АХ – EAX.

Сегментні регістри залишилися 16-бітовими, але до них додалося два нові регістри – FS і GS.

Структура програми

Програма на асемблері є набором пропозицій мови, кожне з яких займає окремий рядок коду програми, в них м.б. записані:.

  • інструкції процесора, які транслюються в машинний код програми;

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

  • макрокоманди – символьні позначення, які під час трансляції програми заміщаються одним або декількома асемблерними пропозиціями;

Також, каждаяя інструкція програми може мати свою мітку – ім'я, яке однозначно описуватиме місцезнаходження цієї інструкції в програмі. Ім'я мітки пишеться в самому початку рядка і відділяється двокрапкою.

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

При написанні програми можна використовувати такі символи:

  • всі латинські букви: A-Z, а-z. При цьому заголовні і рядкові букви вважаються еквівалентними;

  • цифри від 0 до 9;

  • знаки ? @ $ _ &;

  • роздільники . [ ] ( ) < > { } + / * % ! ' " ? \ = # ^.

Ідентифікатори (імена змінних, констант, влучний) можуть складатися з одного або декількох символів. Як символи можна використовувати букви латинського алфавіту, цифри і деякі спеціальні знаки — _ ? $ @. Ідентифікатор не може починатися з цифри. Довжина ідентифікатора може бути до 255 символів, хоча транслятор сприймає лише перші 32, а інші ігнорує.

Числа в початковій програмі записуються відповідними даній системі счислення цифрами і закінчуються буквою, що визначає систему счислення:

Десяткові числа не вимагають для свого запису яких-небудь додаткових символів. Для того, щоб вказати, що число записано в двійковій системі, в кінці числа додається «b», а для шестнадцатеричной – «h». Якщо число в шестнадцатеричной системі починається з букви, то спочатку числа дописується нуль.

Наприклад, число 161 можна записати як: 161, 0a1h, 10100001b.