Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Книга_Вычисл техн и микропроц_2 автора_130709.doc
Скачиваний:
9
Добавлен:
07.05.2019
Размер:
5.26 Mб
Скачать

9.3 Мова програмування Асемблер-86

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

  1. Що входить до поняття “архітектура мікропроцесорів”?

  2. В чому полягає різниця між мовами програмування високого і низького рівнів?

  3. Як можуть будуть подані дробові числа в обчислювальній системі?

  4. В яких кодах подаються числа зі знаком в обчислювальній системі?

  5. Наведіть регістрову модель 16-розрядного МП фірми Intel.

  6. Які сегменти існують в основній пам’яті МПС, побудованої на МП фірми Intel?

  7. Які способи адресування операндів МП фірми Intel Ви знаєте?

  8. Що називається стеком і як його організовано?

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

Мова Асемблер – це машинно-орієнтована мова, яка дозволяє використовувати усі структурні особливості мікропроцесорної системи, що пов’язані з апаратними можливостями, набором машинних команд, складом периферійного обладнання тощо. Мова Асемблер – це символічне подання машинної команди у вигляді її мнемонічного зображення. Програмування на Асемблері вимагає знання способів подання й оброблення даних на рівні машинних команд, що забезпечується знанням різних систем числення та архітектури МПС. Мова Асемблер поєднує у собі переваги машинної мови і деякі особливості мов високого рівня. Асемблер є найбільш ефективною мовою програмування при розв’язанні задач розробки системного програмного забезпечення, розробки програм для обміну даними з нестандартним периферійним обладнанням (драйвери), програмуванням систем реального часу для керування технологічними процесами й обладнанням, а також для забезпечення роботи інформаційно-обчислювальних систем та ефективного використання можливостей (робота у захищеному режимі) і ресурсів МПС.

Мова Асемблер мікропроцесорів фірми Intel є досить розвиненою і гнучкою. До складу мови Асемблер-86 входять понад 100 базових команд, відповідно до яких генерується понад 3800 машинних команд; близько 20 директив, призначених для розподілення пам’яті, ініціалізації змінних, умовного асемблювання тощо. Також у ній передбачено використання засобів структурування даних, що є характерним для мов програмування високого рівня.

Всі команди мови Асемблер можливо поділити за групами, відповідно їх функціональному призначенню: пересилання даних, арифметичні операції, логічні операції і зсуви, передачі керування, оброблення рядків даних і команди керування станом центрального процесора.

Сукупність команд і директив, що представляють текст програми, називаються початковим модулем. Початкові модулі створюються за допомогою текстового редактора і можуть зберігатися на будь-якому носії у вигляді початкового файла. Цей файл може мати будь-яку назву і розширення .asm. Асемблер перетворює початковий модуль в об’єктний модуль. Ця операція називається трансляцією, а програма, яка її виконує – транслятором. На етапі створення об’єктного модуля виконується перетворення команд Асемблера на машинні команди. У результаті роботи транслятора створюються: об’єктний модуль – файл, який має розширення .obj, файл лістинга, який має розширення .lst і файл перехресних посилань з розширенням .crf. Файл лістинга вміщує код Асемблера початкової програми, для кожної команди якої вказано машинний код і зміщення у кодовому сегменті, крім того, до цього файла входять таблиці з інформацією про мітки і сегменти, які використовуються у програмі і повідомлення про синтаксичні помилки. Імена файлів призначає програміст, вони можуть співпадати, а можуть бути різними.

Після створення об’єктного модуля він оброблюється за допомогою програми-укладача, яка генерує завантажувальний модуль. Це файл, який має розширення .exe і який може виконуватися МПС. Програма-укладач у завантажувальному модулі об’єднує об’єктні модулі, що входять до програми і підключає, за необхідності, бібліотечні модулі і замінює відносні адреси комірок пам’яті на абсолютні, з урахуванням області пам’яті, в яку модуль буде завантажено для виконання. Бібліотечні модулі – це об’єктні файли, які містять найбільш поширені програми. Ім’я завантажувального модуля також призначає програміст. Блок-схему алгоритму підготовки програми на мові Асемблер для її виконання показано на рис. 9.8.

Текст програми на мові Асемблер складається з операторів (речень) чотирьох типів:

  • команди, які є символічними аналогами машинних команд МПС;

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

  • директиви – інструкції транслятору з виконання певних дій;

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

Рисунок 9.8 – Блок-схема підготовки програми для її виконання

Довжина речення становить 131 символ, усі інші ігноруються. Речення повинно розташовуватися у межах одного рядка, переносити речення на інший рядок не дозволяється. Речення Асемблера формуються із найпростіших конструкцій мови – лексем, синтаксично нероздільних послідовностей допустимих символів алфавіту Асемблера, які мають значення для транслятора. Як символи алфавіту Асемблера використовуються:

  • усі літери латинського алфавіту, при цьому великі і малі літери є еквівалентні;

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

  • спеціальні і розподілювальні символи, до яких відносяться: ?, @, $, _, &, [ ], ( ), < >, { }, +, –, /, *, %, !, “ “, \, =, #,^ і деякі недруковані символи.

До лексем відносяться: ідентифікатори, рядки символів, цілі числа двійкової, шістнадцяткової або десяткової систем числення.

Ідентифікатор – це послідовність символів, яка визначена програмістом і використовується для іменування об’єктів програми (міток, змінних, назв операцій тощо). Ідентифікатор може складатися з одного або кількох символів, але починатися може лише літерою. Крапка може бути лише першим символом ідентифікатора. Інші спеціальні символи використовувати в ідентифікаторах не дозволяється. Довжина ідентифікатора становить до 255 символів, але транслятор сприймає лише 32 перших символи, інші ігноруються.

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

Рядком символів може бути будь-яка послідовність символів, в якості яких можливо використовувати літери і спеціальні символи, крім символа повернення каретки та перенесення рядка. Рядок символів обов’язково брати у лапки.

Через те, що мікропроцесор може працювати з різними сегментами, то для завантаження і роботи програми необхідно задати сегменти й особливості їх використання. Це робиться за допомогою директиви SEGMENT, яка має вигляд:

{Ім’я сегмента}

SEGMENT

{Тип вирівнювання}

{Тип комбінування}

{Клас сегмента}

{Тип розміру}

Програма

{Ім’я сегмента}

END

Розглянемо окремі поля цієї директиви.

Тип вирівнювання – повідомлення програмі-укладачу про адресу початку сегмента. При правильному розміщенні програма виконується швидше. Можливі значення:

  • BYTE – вирівнювання не виконується. Початкова адреса сегмента може бути будь-якою;

  • WORD – сегмент починається з адреси, яка є кратна 2, при цьому молодший значний біт фізичної адреси дорівнює 0. Виконується вирівнювання по межі слова;

  • DWORD – сегмент починається з адреси, яка є кратна 4. Виконується вирівнювання по межі подвійного слова;

  • PARA – сегмент починається з адреси, яка є кратна 16, при цьому остання шістнадцяткова цифра фізичної адреси дорівнює 0Н. Виконується вирівнювання по межі параграфа;

  • PAGE – сегмент починається з адреси, яка є кратна 256. Виконується вирівнювання по межі сторінки;

  • MEMPAGE – сегмент починається з адреси, яка є кратна 4 кбайтам.

За умовчанням тип вирівнювання має значення PARA.

Тип комбінування – повідомлення програмі-укладачу про об’єднання при виконанні сегментів різних модулів програми, які мають однакові імена. Можливі значення:

  • PRIVATE – сегмент не об’єднується з іншими сегментами;

  • PUBLIC – об’єднуються усі сегменти з однаковими іменами. Сегмент, що отримаємо, буде цілий і безперервний, а всі адреси будуть формуватися від його початку;

  • COMMON – усі сегменти з однаковими іменами розміщуються за однією адресою. Таким чином, усі сегменти будуть перекриватися і сумісно використовувати пам’ять;

  • AT xxxx – розміщує сегмент за абсолютною адресою параграфа, адреса якого задається виразом хххх;

  • STACK – визначення сегмента стека. Усі сегменти, що мають однакові імена, об’єднуються таким чином, що їх адреси розраховуються відносно вмісту регістра SS.

Клас сегмента – повідомлення про відповідний порядок включення сегментів при складанні програми із сегментів різних модулів. Програма-укладач з’єднує усі сегменти, що мають однаковий клас. Рекомендується об’єднувати сегменти з однаковим функціональним призначенням (наприклад, сегменти коду програми). Клас сегмента – це рядок, який береться у лапки, наприклад, сегмент коду «CODE».

Тип розміру сегмента – задає розмір сегмента і порядок формування фізичної адреси в ньому, тому що дані можуть бути 16- або 32-розрядними. Може приймати такі значення:

  1. USE16 – формування фізичної адреси у такому сегменті виконується тільки з 16-розрядним зміщенням. Розмір такого сегмента 64 кбайт.

  2. USE32 – формування фізичної адреси у такому сегменті виконується тільки з 32-розрядним зміщенням. Розмір такого сегмента 4 Гбайт.

Для призначення сегментам конкретного функціонального призначення і закріплення їх за сегментними регістрами використовується директива ASSUME, яка має вид:

ASSUME

Назва сегментного регістра;

Ім’я сегмента

Для простих програм, що мають по одному сегменту для коду, даних і стека, у найбільш поширених трансляторах TASM i MASM для спрощення директив сегментування уведено директиву зазначення моделі пам’яті MODEL, яка частково керує розміщенням сегментів. Ця директива зв’язує сегменти, які при використанні спрощених директив сегментування мають наперед визначені імена з сегментними регістрами. Обов’язковим параметром цієї директиви є модель пам’яті. У табл. 9.1 наведено назви і значення параметрів директиви MODEL.

У цій таблиці поняття near і far характеризують віддаленість об’єкта від місця використання. Якщо об’єкт розташовано у сегменті разом з кодом і звернутися до нього можливо за допомогою двобайтового зміщення, то це відповідає типу near (близький перехід). При цьому команда модифікує лише вміст вказівника команд ІР. В іншому випадку об’єкт розміщується в іншому сегменті (тип far) і для звернення до нього необхідно надати чотирибайтний вказівник – сегмент: зміщення. При цьому буде модифіковано вміст двох регістрів.

Таблиця 9.1 – Назви і параметри моделей пам’яті

Модель

Тип коду

Тип даних

Призначення моделі

TINY

near

near

Код і дані поєднано в одну групу з ім’ям DGROUP. Використовується для створення програм з розширенням .com

SMALL

near

near

Код займає один сегмент, дані об’єднано у одну групу з ім’ям DGROUP. Ця модель, звичайно, використовується для створення програм мовою асемблера

MEDIUM

far

near

Код займає декілька сегментів, по одному на кожен програмний модуль, що об’єднується. Усі посилання на передачу керування – типу far. Дані поєднано в одній групі. Усі посилання на них – типу near

COMPACT

near

far

Код знаходиться в одному сегменті. Дані можуть бути у різних сегментах. Посилання на них типу far

LARGE

far

far

Код займає декілька сегментів, по одному на кожен програмний модуль, що об’єднується. Усі посилання типу – far

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

  • db – резервування пам’яті для даних довжиною 1 байт;

  • dw – резервування пам’яті для даних довжиною 2 байта (слово);

  • dd – резервування пам’яті для даних довжиною 4 байта (подвійне слово);

  • df – резервування пам’яті для даних довжиною 6 байт;

  • dq – резервування пам’яті для даних довжиною 8 байт;

  • dt – резервування пам’яті для даних довжиною 10 байт.

Нижче наведено приклад використання директив для керування програмою на мові Асемблер.

MODEL SMALL ; Тип моделі пам’яті, що буде

; використовуватися

STACK 256 ; Визначення сегмента стека

DATA SEGMENT ; Визначення сегмента даних

DATA ENDS

CODE SEGMENT ; Визначення сегмента коду

ASSUME CS:CODE,DS:DATA,ES:DATA ; Закріплення сегментних

; регістрів

· ;

· ; Програма

· ;

CODE ENDS ; Кінець коду програми

END ; Закінчення

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

  1. Які особливості мови Асемблер забезпечують її використання?

  2. Які файли формуються у результаті роботи програми-транслятора?

  3. Чому виконання асемблерної програми можливо лише після роботи програми-укладача?

  4. Які файли використовує програма-укладач для формування завантажувального модуля?

  5. Які оператори (речення) можуть входити до тексту програми на мові асемблера?

  6. Які моделі пам’яті Ви знаєте? Чим відрізняються поняття near і far?

  7. Які директиви використовуються для опису простих типів даних?

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

  1. Для чого використовуються різні типи комбінування?

  2. Яким чином програмувач задає типи сегментів і особливості їх використання?

  3. Які директиви резервування й ініціалізації даних Ви знаєте?