
- •Методичні вказівки
- •"Системне програмування та операційні системи”
- •Лабораторна робота №1
- •Загальні відомості
- •Компілятор Turbo Assembler
- •Компонування програми
- •Складові частини програми
- •Приклад побудови програми
- •Завдання до лабораторної роботи №1
- •Лабораторна робота №2
- •Програмна модель пристрою fpu
- •Варіанти завдань до лабораторної роботи №2
- •Лабораторна робота №3
- •Опис логічних операцій мови програмування асемблер
- •Приклад програми використання логічних операцій
- •Варіанти завдань до виконання лабораторної роботи №3
- •Лабораторна робота №4
- •Команди для роботи з масивами
- •Приклад програми для роботи з масивами
- •Варіанти завдань до виконання лабораторної роботи №6
- •Лабораторна робота №5
- •Команди для роботи зі стрічками
- •Приклад програми для роботи із стрічками
- •Варіанти завдань до виконання лабораторної роботи №5
- •Контрольні запитання
- •Порядок оформлення звітів до виконання лабораторних робіт
- •Література
- •Навчальне видання
- •« Системне програмування та операційні системи »
Компонування програми
З метою створення виконавчого модуля програми слід здійснити компонування результуючих модулів з бібліотечними. Цю задачу покладають на компонувальника Turbo Link фірми Borland.
Звернення до компонувальника в загальному випадку має вигляд: TLINK obj, exe, map, lib. Obj є ім’ям результуючого файлу, що підлягає компонуванню або послідовність таких імен, розділеними прогалинами або “+”. Exe – ім’я файлу, куди буде поміщено скомпонований модуль програми; map – ім’я файлу, де буде розміщено протокол збірки; lib – ім’я бібліотеки або послідовність таких імен, розділені прогалинами або “+”.
Якщо параметри exe або (і) map будуть пропущені, то по замовчуванню їм присвоїться ім’я obj-файлу, а розширення вони матимуть відповідно .EXE та .MAP.
Якщо при зверненні до компонувальника не буде параметрів, то він видасть допомогу по них:
/с – розрізняти великі та малі букви в зовнішніх символах;
/d – видавати інформацію про один і той самий символ, що зустрічається більше, ніж в одній бібліотеці;
/е – ігнорувати розширений словник зовнішніх модулів;
/і – розміщати в .EXE-файлі кінцеві сегменти, навіть якщо в них немає записів даних;
/l – поміщати в карту збірки інформацію про номери строк вихідного модуля;
/m – доповнити карту збірки переліком символів, що досяжні зі всіх модулів;
/n – ігнорувати бібліотеки, що є по замовчуванню;
/s – доповнити карту зборки словником доступних символів, а також схемою сегментів;
/t – якщо модуль компілювався в моделі TINY, то виконавчий файл зробити у форматі .COM, а не .EXE.
/v – включити у виконавчий файл інформацію, необхідну для ініціалізації програми;
/x – відмінити генерування карти зборки.
Складові частини програми
Будь-яка програма, написана на мові асемблера, складається із рядків вигляду: label directive comment або label: command comment, в яких label – мітка, directive і command – відповідно директива та команда, а comment – коментар. Мітка, що стоїть перед командою, разом з “:”, що її позначає, може міститися в окремій лінійці. Коментар – це послідовність символів, що компілятор ігнорує, які відділяються “;”. Наявність мітки та коментарю не є обов’язковою. Ідентифікатор, з котрого починається остання лінійка структурної директиви, не може бути міткою.
Приклад директив і команд
ASSUME CS:Code ; мітка Code
Code SEGMENT
Fix DB 12 ; директива DB з міткою
Start: ; мітка Start
mov ax, Code ; звернення до мітки Code
Code ENDS ; звернення до мітки Code
Stack_ SEGMENT STACK ; початок структурної директиви
Stack_ ENDS ; кінець структурної директиви
END Start ; звернення до мітки Start
Ключові слова являють собою записи з фіксованим значенням, з якого починається кожна директива і команда.
Мітка – являє собою ідентифікатор, котрий може додаватися до директиви чи команди. Мітка складається з послідовності букв та цифр (починається лише з букви). Мітки поділяються на мітки констант (Fatal EQU 7), змінних (Value DB -77), мітки команд (Start: mov ax, 07h), сегментів (Data SEGMENT … ENDS), процедур (Fun PROC … ENDP), макровизначень (Shift MACRO … ENDM).
Якщо мітка з’являється перед командою, то вона відділяється від неї двокрапкою. В кожному вихідному модулі дана мітка може визначатися лише один раз, але кількість звернень до неї не обмежена.
Літерали – це імена постійних величин. Вони класифікуються на арифметичні, символьні та стрічкові. Арифметичні літерали, в свою чергу, поділяються на цілочисельні та дійсні. Цілочисельні можуть бути десятковими, шістнадцятковими та двійковими. Десятковий літерал – це послідовність чисел від 0 до 9. Шістнадцятковий літерал – це послідовність шістнадцяткових чисел (від 0 до F), яка закінчується символом h. Двійковий цілочисельний літерал складається з послідовності 0-ів та 1-ць, після якої є символ ‘b’. Десятковий літерал з плаваючою комою складається з цілої частини, десяткової крапки, дробової частини, символу ‘E’ і показника степеня. Символьний літерал складається з існуючого символу коду ASCII, що взятий в апострофи чи лапки. Стрічковий літерал складається з існуючих символів коду ASCII, взятій в апострофи чи лапки.
Команда – це запис, що визначає дію, яку повинен виконати процесор. Команди за кількістю операндів поділяються на команди без операндів, з одним операндом, з двома операндами. У відповідності з цією класифікацією команди можуть бути представлені у відповідності до одного з наступних записів:
action (наприклад, movsb)
action (наприклад, int 21h)
action (наприклад, mov ax, 12)
В двомісних командах перший операнд є результатом, а другий – аргументом. Деякі команди мають операнди по замовчуванню. В цьому випадку класифікація операндів на аргумент та результат здійснюється згідно опису команди.
В момент початку виконання програми коректними вважаються виключно команди мікропроцесора Intel 8086 та сопроцесора Intel 8087. Для виконання команд інших мікропроцесорів слід скористатися директивами вибору процесора, кожна з яких складається з символу “.”, після котрого йде номер процесора, наприклад 80286 або 80287.
Директива – це команда, в результаті інтерпретації котрої проходить визначення змінної, константи, макровизначення чи визначення подальшого способу компіляції. Мнемокоди директив являють собою ключові слова і можуть бути записані як малими, так і великими латинськими літерами. Деякі директиви є структурними і повинні супроводжуватись іншими директивами. До цієї групи директив відносять директиви умовної компіляції, макродирективи, а також сегментні директиви та директиви процедур. Наприклад, директива SEGMENT використовується за схемою:
lab SEGMENT align combine class
body
lab ENDS
Тут lab являє собою мітку сегмента, align визначає спосіб розміщення сегмента в оперативній пам’яті, combine визначає спосіб об’єднання декількох сегментів, що відповідають одній і тій самій мітці (ці сегменти входять в різні модулі), в один сегмент, а class визначає включення об’єднаного сегмента в ту групу сегментів, котра буде займати сусіднє положення в оперативній пам’яті. В результаті інтерпретації приведеної директиви створюється сегмент з іменем lab. Якщо в деякому вихідному модулі є декілька сегментних директив з міткою lab, то всі вони неявним чином об’єднуються в одну сегментну директиву. В цьому випадку операнди align, combine, class повинні міститися лише в першій директиві, а в усіх наступних директивах ці операнди ігноруються. Якщо сегментні директиви з однією міткою містяться більше, ніж в одному вихідному модулі, то явні параметри чи ті, що є за замовчуванням, повинні бути ідентичними. Перелічені операнди можуть виглядати таким чином:
align
byte розміщення сегмента на границі байта
word -“- слова
dword -“- подвійного слова
para -“- параграфу (за замовчуванням)
page -“- сторінки
combine
private заборона об’єднання з сегментами інших модулів (за замовч)
public об’єднати модулі таким чином, щоб об’єм об’єднаного сегменту дорівнював сумі об’ємів його складових
common -“-, щоб перші байти кожного сегменту, що об’єднуються, співпадали, а довжина об’єднаного сегменту була рівною довжині максимального складового
stack те саме, що public, але об’єднаний сегмент є стеком
memory те саме, що public, але об’єднаний сегмент є областю вільної оперативної пам’яті
at exp команда інтерпретувати сегмент так, ніби він починається з розділу, номер котрого є рівним exp, але без генерації даних та коду.
class цей операнд являє собою символ, замкнений апострофами або лапками, і означає ім’я класу, до якого буде віднесено даний сегмент.
Вирази можуть використовуватись як в якості параметрів в директивах оголошення змінних, так і в ролі операндів у командах. Необхідно лише, щоб значення виразу було визначено до початку виконання програми. Завдяки цьому в кожному місці програми, в якому може з’явитися число, може появитися і вираз. Синтаксис виразів на мові Turbo Assembler ближчий до синтаксису мови С. Зокрема це виявляється в тому, що аналіз коректності та семантичний аналіз можуть бути здійснені виключно за пріоритетом використаних в ньому операторів. Приведемо список операторів за спаданням пріоритетів:
() [] LENGTH MASK SIZE WIDTH
.
+ - (одномісні оператори плюс та мінус)
:
OFFSET type* PTR SEG THIS TYPE
* / MOD SHL SHR (двомісні оператори множення та ділення)
+ - (двомісні оператори додати та відняти)
EQ GE GT LE LT NE
NOT
AND
OR XOR
SHORT
type* означає одне з перелічених далі ключових слів: FAR, NEAR, BYTE, WORD, DWORD, FWORD, QWORD, TBYTE).