.

Програмування на мові асемблера.(курсова)

Язык: украинский
Формат: реферат
Тип документа: Word Doc
20 5256
Скачать документ

Курсова робота

Програмування на мові асемблера

Вступ.

Після створення процесора 8086 фірма Intel розробила більш досконалі
процесори об’єднані під назвою I 80×86, така назва означає, що всі
команди мікропроцесора, які виконуються на молодших моделях обов’язково
виконуються на старше, отже все ПЗ, які розроблені для процесора 8086
успішно будуть працювати і на останніх моделях 80486 і Pentium. Ми
будемо розглядати процесори з точки зору програміста. Не дивлячись на
різноманітність моделей процесорів, найбільш важливим з точки зору
біології програмування є 8086 як базова модель і 80386 , як перший
процесор фірми Intel, який в повному об’ємі реалізував принцип
багатозадачності.

Програмування на мові асемблера

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

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

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

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

Етапи створення програми.

Розробка програми на мові асемблера включає кілька етапів.

Підготовка початкового тексту програми;

Асемблювання програми(отримання об’єктного коду);

Компоновка програми(отримання виконуваного файлу);

Відладка програми(знаходження помилок).

Ці етапи циклічно повторюються.

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

Текст програми на мові асемблера записується в один або кілька файлів,
імена файлів і їх розширення можуть бути будь-які, прийнято для файлів
які містять програми мовою асемблера прийнято використовувати розширення
*.asm. Для файлів визначених констант і повних типів розширення *.inc.
Ці файли є текстовими їх можна набрати в будь-якому текстовому
редакторі. Можна також використати інтегровані середовища для розробки
програм, при програмуванні зручно виділяти один каталог для збереження
всіх файлів програми і звідти запускати всі необхідні програми для
підготовки, асемблювання та компонування програми. При використанні
стандартних редакторів тексту, редаговані тексти треба зберігати у
вигляді звичайних файлів у форматі ASCII, це означає, що ці файли треба
зберігати без додаткових символів, ці символи часто вставляють в текст
різні спеціалізовані редактори, наприклад WORD.

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

Підготовлений текст мови асемблер є початковим для спеціальних програм,
які називаються асемблерами, далі програма асемблера. Задача програми
асемблера перетворити текст програми у форму двійкових команд, останні
можуть вже бути виконанні мікропроцесором. Після асемблювання дістають
так звані файли об’єктних модулів, які мають відповідні розширення
*.obj. Для отримання об’єктних файлів необхідного виконати відповідну
програму асемблера masm фірми Microsoft, або tasm фірми Borland. В обох
випадках після команди вказується ім’я файлу : masm prog1.asm, tasm
prog1.asm.

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

Компоновка програми.

Текст програми може знаходитись в декількох файлах, змінні які описані в
цих файлах можуть використовуватися спільно, якщо такі файли
асемблюються окремо, то не можливо дістати повну інформацію, для того,
щоб генерувати виконавчий код. Тому процес підготовки програми
обов’язково включає в себе етап компоновки. На цьому етапі визначають
всі невідомі, при окремому асемблювані, адреси всіх змінних або функцій,
які використовуються спільно. Процес об’єднання об’єктних модулів в один
файл виконується спец. програмою, яка називається компоновщиком. Це може
бути програма link фірми Microsoft, або tlink фірми Borland, отримуваний
виконуваний файл має розширення *.exe, або *.com. Компановщику треба
передати імена відповідних об’єктних файлів.

Link prog1.obj prog2.obj

Tlink prog1.obj prog2.obj

Після компонування отримується виконуваний файл, він отримує ім’я файла,
який стоїть перший у відповідній команді.

Відладка програми.

За винятком початкових простих програм практично всі програми на мові
асемблера мають потребу в відладці. Для відладки можна використовувати
різні відладчики, наприклад tg386-Turbo Debuger фірми Borland. Сучасні
відладчики дозволяють в процесі відладки контролювати значення регістрів
загального призначення, а також значення змінних і змінювати їх в
процесі відладки, можна переглядати зміст різних ділянок пам’яті, можна
контролювати виконання покроково, або розставляти точки зупинки.

Використання інтегрованих середовищ (ІС).

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

Основні відомості та правила для написання програм на асемблері.

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

При записі чисел в 16-вій системі числення треба враховувати, що для
чисел 10-15ами.

За винятком пбукви латинського алфавіту. Щоб відрізнити 16-ві числа
дописується суфікс Н або h, крім того перш0пбуква в записі
шістнадцяткового числа повинн0пбути арабською цифрою. Тобто для
написання числа c5h не достатньо суфікса h, треба обов’язково поставити
спершу 0:0C5h. За умовчанням використовується десяткове CЧ. При допомозі
директиви radix можна міняти CЧ.

Двійкові числа.

Для великої кількості команд допускається, що інформація представлена в
двійкових кодах, довжина цих двійкових чисел може бути різною.
Мікропроцесори сімейства І 80х86 підтримують дані таких розмірностей:

Байти;

Слова;

Подвійні слова;

Рядки.

Крім того до специфічних даних можна віднести адрес переходів. Байт – це
мінімальна к-сть інформації при роботі мікропроцесора, складається із 8
біт. Вся пам’ять мікропроцесора може розглядатись як велика к-сть
байтів.

210б=1Кб

220б=1Мб

230б=1Гб

240б=1Тб

Так як байт складається з 8 біт, кожен біт може перебувати в двох
станах, то байт може перебувати в 256-тьох станах. Крім представлення
чисел байт використовується для збереження символьних кодів, наприклад
це може бути символ, що набирається з клавіатури. 256 різних значень
байта дозволяють описати з допомогою ASCII не тільки десяткові числа, а
й весь англійський алфавіт, а також знаки пунктуації, спеціальні знаки,
управляючі символи, символи національних алфавітів. Слово може містити
216=65536 різних станів, а це є 64 Кб. Слово це найбільш зручний спосіб
збереження інформації в даному сімействі мікропроцесорів, адже їх
внутрішні регістри як мінімум 16-ти розрядні. У всіх мікропроцесорів
фірми Intel правило запису багатобайтних чисел таке: молодший байт
знаходиться за молодшою адресою в пам’яті, старший за старшою адресою.
Адреса деякої ділянки пам’яті яка розглядається як слова рівна адресі
молодшого байту. Наприклад, якщо за адресою N записано слово 1539H, то
це означає, що за адресою N записаний байт 39H, а за адресою N+1 – 15Н.
Важливим є число 65536, для процесорів 80х86 це число визначає
максимальну довжину сегменту, тобто області пам’яті, яка містить код або
данні програми, тому за допомогою таких чисел до 65536 можна адресувати
комірки пам’яті всередині даного сегменту, така адресація, коли
використовується зміщення всередині сегменту називається ближньою –
Near. Подвійні слова рівні 4 байт, або 32 біт. Одне слово може мати
4294967296=4Мб. Подвійні слова зберігаються в пам’яті за цим же
правилом: молодший байт за молодшою адресою, байти в пам’яті
розташинятком ппослідовно один за одним 12554959Н – слово подвійне, якщо
воно знаходиться за адресою N, то за адресою N знаходиться байт 59Н, N+1
– 49H, N+2 – 55H, N+3 – 12H. Подвійне слово при програмуванні для
процесорів молодших 80386 має достатньо місця для збереження не тільки
адреси всередині сегменту, а й адреси початку сегменту і адреси зміщення
в середині сегменту називається дальньою – for adress адресою. При
програмуванні , коли для завдання адреси використовується 32 біти (для
мікропроцесорів 80386 і старше) в подвійному слові кожна зберігати
32-розрядне зміщення. За допомогою цього зміщення можна звертатись до
будь-якої комірки пам’яті. Рядки в мікропроцесорах родини І 80х86 можна
виконувати операції над рядками. Рядок – це послідовність байтів або
слів, а для мікропроцесорів старших 80386 подвійних слів, які
знаходяться в пам’яті комп’ткера. Мінімальна довжина рядку 1 елемент,
максимальна довжина рядку може досягати 64 Кб для мікропроцесорів
молодших 80386, і 4Гб для мікропроцесорів старших 80386.

Представлення чисел зі знаком.

Мікропроцесори даної родини підтримають обробку чисел зі знаком, для
чисел, які мають розмірність байт, слово, подвійне слово. Для
представлення знаку використовують самий старший розряд числа 0 – “+”, 1
– “-“. В зв’язку з цим діапазон представлення чисел звужується.
Наприклад для байтів зі знаком мінім. число : -128, макс. число : 127.
Відповідно слово зі знаком : -32768 і 32768, подвійне слово :
-2147483648 і 2147483647.

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

Двійково-десяткові числа.

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

За винятком птетради, які відповідають числам a – f 16-вої СЧ.
Мікропроцесори цьої родини підтримують роботу з двома форматами
двійково-десяткових чисел: унакованими і неунакованими
двійково-десятковими числами.

Вони займають 1б – 2птетради.

0 0

отже при допомозі однобайтного двійково-десяткового числа можна записати
десяткові числа 0 – 99.

9 9

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

Неунаковані двійково-десяткові числа.

Як і унаковані вони займають 1б, але в цьому байті записується тільки
одна десяткова цифра, ця цифра записується в молодшій тетраді:

0 – 9

Отже діапазон представлення чисел 0 – 9. Значення старшоWптетради не
суттєве:

9

Для зручності відладки в старшCптетраду записують 0:

0 0 0 0

0 –9

Зворотне представлення просте: молодш0птетрада, якщо вона знаходиться у
межах представлення чисел 0 – 9 визначає відповідне двійково-десяткове
неунаковане число. При необхідності працювати з великою розрядністю
таких чисел необхідно використовувати також кілька байт.

Приклад структури програми на мові асемблера (ш0блон).

Приведемо основні директиви, які використовуються і програмі на мові
асемблера. Тепер використовуються спрощені способи опису сегментів.
Сегменти – це частини програми (сегменти даних). Текст програми можна
набирати великими або малими буквами, програма асемблера самостійно
переводить текст у верхній регістр. Обов’язково у тексті програми писати
коментарі. Текст який стоїть за символом “;” є коментарем, він
ігнорується при асемблюванні програми. Директива яка як правило йде з
початку програми dosseg описує розташування сегментів. Директива mode
small – директива опису моделі пам’яті, наприклад в цьому випадку
говорять, що модель пам’яті типу small, тобто є один сегмент коду і один
сегмент коду і один сегмент даних. Директива .stack 100 – директива, яка
задає початок сегменту стеку. В стеці зберігаються тимчасові змінні і
адреси повернення з підпрограми або переривань. Як правило будь-яка
програма має сегмент стеку. В даному випадку такий запис директиви
.stack 100 позначає, що стек має довжину 100байтів. Точну величину стеку
визначає число викликів підпрограм та системних ф-цій, стек треба
збільшувати. В кінцевому підсумку розмір стеку підбирають
експериментально, коли програма вже написана і відлагоджена. Директива
.data – директива початку сегменту ініціалізованих даних, після цього
рядка поміщають змінні значення яких відоме (ініціалізовані змінні).
Директива .data ? – директива початку сегменту неініціалізованих даних.
Директива .code – початок сегменту коду. Сегмент коду – це частина коду
яка містить команди МП, власне це й є сама програма. В деяких випадках в
цей сегмент можна поміщати не тільки команди, а й дані. Наприклад у
підпрограмах обробки переривань. Директива .startup – точка початку
виконання програми. З наступного після даного рядка починається
виконання програми після її завантаження в пам’ять, ця директива
повинн0пбути обов’язково всередині сегмента коду, але не обов’язково
н0пйого початку. Директива .exit 0. – це директива закінчення програми
при виконанні цього рядка управління буде передане ОС. Таких директив в
програмі може бути кілька, число після директиви може приймати кілька
значень, це число після закінчення програми присвоюється змінній ОС з
назвою ERRORLEVEL, ця змінна використовується в командних файлах. Є
спеціальні команди для роботи з цією змінною. Використовуючи різні числа
можна повідомляти ОС, яка причина закінчення програми. Директиви початку
і закінчення програми є по суті макровизначеними, вони визначають
необхідний код який автоматично додається на початок і кінець програми.
Цей код можна подивитись у файлі лістингу після асемблювання. End –
директива закінчення тексту програми на мові асемблера. Рядки які
розміщені після директиви end можна писати коментар в довільній формі.

Команди мови асемблера.

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

Рядок 1 \

Рядок 2 Рядок 1 Рядок 2.

CJHaJH

`

b

c

&

&

dh`„?

dh`„?

dh`„?a$

&

ioooeOOOOoAEAEAEAEooAEoeeAEoo

&

dh`„?

dh`„?

dh`„?a$

dh`„?a$

???????????а, директиви інакше називають псевдооператорами. Команда
мікропроцесора – це інструкція яку мікропроцесор буде виконувати в
процесі виконання програми. Асемблер переводить рядки з мнемоніками
(буквеними записами команд) у послідовності байт, які безпосередньо може
виконувати процесор. Директиви служать для визначення даних, які
використовуються в програмі і для управління процесом асемблювання.
Рядок у програмі на мові асемблера може складатися з 4 полів:

Поле мітки (поле імені);

Поле оператора (або псевдооператора);

Поле операндів;

Поле коментарів.

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

[]: ; коментарі

; коментарі

Потрібно звернути увагу на відсутність “:” після імені. Поля в рядках
мови асемблера розділяються між собою на крайній мірі одним пропуском.
Розглянемо поля детальніше. Поле мітки. При визначенні в програмі мітки
або імені змінної можна використовувати букви латинського алфавіту
великі або малі, а також символи 😕 _ @ $. Максимальна к-сть символів з
яких може складатись мітка або ім’я 255, але відрізняються мітки та
імена по перших 32символах. Доцільно в програмі використовувати
осмислені імена. Зручно і програмі для швидкого розпізнавання міток від
імені починати всі мітки з букви L і записувати їх тільки великими
буквами. При записі імен змінних зручно використовувати префікс, який
означає тип змінної, наприклад : skp_byte. При програмуванні з
використанням асемблера masm, або tasm можна використовувати будь-яке
число локальних міток @@. Для переходу до таких міток треба
використовувати зарезервовані слова: @F – forward; @B – backward.
Перш0п@F – це перехід до наступної мітки, @B – це перехід до попередньої
мітки. Мітка або ім’я змінної не повиннVпбути зарезервованим словом.

Поле операндів.

Поле операндів залежить від попереднього поля.

Поле коментарів.

Структура програми на мові asm.

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

За вання сегментів є спробою заха вити незв’язані ділянки пам’яті в
програмі. Допускалось, що для того, щоб визначити адресу деякої комірки
пам’яті потрібно знати дві складові цієї адреси: адресу початкового
сегменту та адресу зміщення комірки пам’яті від початку сегменту. Адреси
початків сегментів знаходяться у відповідних сегментах регістрах CS, DS,
SS, ES – змінюючи вміст цих регістрів можна дістати доступ до тих чи
інших ділянок пам’яті, тому такий запис легко зламати. Тому в процесорі
386 в захащеному режимі роботи адреси початків сегментів, їх довжини та
права доступу зберігаються в спеціальних системних одиницях. В
сегментних регістрах зберігають тільки індекс структури всередині
таблиці. Це дозволило ізолювати сегменти та обмежило доступ до них з
програми. Адже для доступу потрібно знати не тільки вміст сегменту
регістру, але й тієї структури на яку він вказує. Така зміна можлива
тільки при використанні привілейованих команд, що виконується тільки в
певних умовах, можуть виконуватись в ОС, але не можуть використовуватись
в програмах користувача. Паралельно з цим збільшення розміру
сегментів:амід 64Кб для 86, до 4Гб для 486. Крім того програма буде
виконуватись, якщо змінити адресу початку сегменту. Це означає, що в
пам’яті він буде перенесений в інше місце. При цьому відносне зміщення в
сегменті не можна зміщувати. Це дозволить переносити програму в пам’яті
навіть під час її виконання. Використання сегментації пам’яті дозволяє
різко збільшити розміри пам’яті, яку можна використати. Так, в
захащеному режимі максимально можливий об’єм пам’яті, яку можна
адресувати – 64Тб. Це віртуальна пам’ять. Тоді як фізичний об’єм пам’яті
складає 4Гб. В деяких випадках використовувати сегментацію недоцільно.
Тому в старших моделях можна працювати із сегментами довжиною до 4Гб. Це
означає, що вся фізична пам’ять розглядається як один сегмент. Повністю
усі переваги сегментації пам’яті проявляється в захащеному режимі
роботи. В реальному режимі роботи оперує з 4-ма сегментами:а

Сегмент коду;

Сегмент даних;

Сегмент стеку;

Сегмент додаткових даних.

Для процесорів 386 з’явились ще 2 сегменти додаткових даних. Ці сегменти
в пам’яті можуть розташиняватись як завгодно по відношенню один до
одного. Ніяких обмежень на їх розташування немає. Сегменти можуть
починатись з однієї адреси, тобто можуть перекриватись. Вони можуть
розташиняватись в пам’яті без перекривання, або між ними можуть бути
проміжки.

Для визначення адреси наступної команди після виконання попередньої
використовують 2 регістри: CS (регістр сегменту коду, він містить
початок адресу цього сегменту), і IP(регістр вказівника команд, якість
зміщення команди відносно початку сегменту). В процесі виконання
програми вміст ІР автоматично змінюється. Якщо змінити вміст регістрів
CS, та ІР, то виклик програми почнеться з іншої адреси. Але явним чином
змінити вміст цих регістрів неможливо. Це можна зробити тільки при
використані деяких команд. Наприклад при виклику підпрограми. Або
виконані програми безумовного переходу. Як уже відмічалось в сегменті
коду можна також описувати дані. Але це роблять тільки в обгрунтованих
випадках, наприклад в програмі обробки переривань.

Початок програми.

В початковій версії необхідно було відмітити точку входу в програму
деякою міткою. Ім’я цієї мітки потім вказувалось в директиві end. Це
було ознакою закінчення файлу з програмою. У сучасних асемблерах для
визначення точки входу в програму використовується директива startup.
Вона записується в сегменті коду, це спрощує запис і, крім цього,
автоматично ініціалізує значення сегментних регістрів. В старих версіях
це потрібно було робити вручну.

Кінець програми.

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

Змінні в програмі.

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

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

Часто в програмі необхідно мати місце для збереження тимчасових даних.

Сегмент даних.

Використовується для збереження змінних, що визначає програміст. Як
правило це робиться при допомозі псевдооператорів виділення пам’яті. Для
визначення адреси початку сегменту використовується регістр DS. Для
визначення другої компоненти адреси (відповідного зміщення всередині
сегменту) використовується кілька способів адресації. Зауважимо, що
способів визначення адреси змінної набагато більше ніж способів
визначення адреси команди. В мові асемблер є засоби для явного розділ.
збереження змінних. Ці змінні можуть мати або не мати початкових
значень, а також можуть бути змінними константами. Розділяти ці типи
змінних не обов’язково. Усіх їх можна зберігати в сегменті даних.

Ініціалізовані змінні.

Змінні, початкові значення яких відоме як правило записуються в
сегменті, що починається директивою data. До цих змінних відносяться
також ті, початкові значення яких відоме і в процесі роботи вони не
повиннVпмінятись.

Неініціалізовані змінні.

Неініціалізовані змінні записуються в сегмент який починається
директивою data.

Сегмент стеку використовується для збереження тимчасових даних для яких
недоцільно виділяти змінні. Адреса початку цього сегменту розміщується в
регістрі SS, а зміщення відносно початку в регістрі SP. Для визначення
сегменту стеку використовується директива stack. Цей сегмент
відрізняється від сегменту даних і коду. В сегменті даних і коду можна
явно адресувати б-я комірку пам’яті. Тут значення регістру при виконанні
команд. В кожний момент часу пара цих регістрів SS і SP вказує на так
звану вершину стеку. Сюди можна записати або прочитати значення. Стек
організований за правилом: перший записаний, останній прочитаний. Тому у
програмі команди запису і зчитування зі стеку потрібно використовувати
попарно. Стек переважно використовується для тимчасового зберігання
адреси повернення з програми або перервань. Ще одне ми.

За вання стеку – при його допомозі можна передавати аргументи
підпрограмам і організовувати локальні змінні.

Моделі пам’яті

Tiny (файл *.com). При цьому регістри CS, DS, SS містять однакові
значення. Це найбільш компактна модель пам’яті. Розмір пам’яті не може
перевищувати 63Кб. Адресація здійснюється за допомогою зміщення і міток.
Оскільки програма на асемблері не є великими, то це не є значним
обмеженням. Ця модель широко використовується, особливо в резидентних
програмах.

Small. Сегмент коду відділений від сегменту стеку і сегменту даних.
Сегмент даних і стеку об’єднані в єдине. Тому CS і DS мають однакові
значення. Це найбільш поширена модель при розробці програм на асемблері.
Всі переходи і виклики підпрограм здійснюються за допомогою короткої
адресації.

Compact. Використовується 1 сегмент коду і можливе ми.

За вання кількох сегментів даних. тому виклики підпрограм і переходи в
програмі є короткими, а доступи до даних – далекими. Сегмент даних і
стек об’єднані в одну групу.

Medium. В значній мірі протилежна до попередніх. Є кілька сегментів коду
і один сегмент даних. Тому доступ до підпрограм і переходи в програмі є
далекими (потрібна адреса сегменту та зміщення). А доступ до даних
здійснюється за допомогою короткої адресації (вказується тільки
зміщення).

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

Huge, Flat. Це досить поширені моделі. Така ж організація пам’яті, як і
в large. Вона використовується для поєднання асемблера змовами високого
рівня. В них можна задати таку модель пам’яті, з’являється можливість
роботи з даними що займають більше 64 Кб. В програмі на асемблері таку
модель використовувати недоцільно. Модель Flat відповідає моделі Small,
різниця в тому, що використовуються 32 розрядні регістри. Таку модель
можна організувати використовуючи процесор вище і80386. Переважно її
використовують для роботи в захащеному режимі. В цьому випадку доступ до
всієї області пам’яті здійснюються за допомогою одного сегменту.

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

Model [ ] .

В цій директиві може бути вказано ще ряд параметрів. Єдиним необхідним
параметром є параметр . Тип можна додатково модифікувати. Для цього
необхідно вказати один із 4 модифікаторів:аnearstack; farstack; use16;
use32. При першому стек і дані розташинані в межах одного сегменту;
farstack вказує, що сегмент даних буде розташинаний за межами стеку.
Nearstack використовується по замовчуванню у всіх стандартних моделях
пам’яті. Він дозволяє організувати інтерфейс з мовами високого рівня.
Тут глобальні дані розміщені в сегменті даних, а локальні – в сегменті
стеку. Два останні модифікатори використовуються тільки для МП 80386 і
старше, вони вказують які сегменти використовуються в програмі,
16-розрядні (64 Кб сегмент) і 32-розрядні (4Гб сегмент). Доцільно
використовувати ці модифікатори при розробці програм при використанні
32-розрядних компіляторів.

Псевдооператори (директиви).

Псевдооператори керують роботою асемблера, а не МП. Вони дозволяють
визначати сегменти і процедури (надавати імена програмам і елементам
даних, резервувати області пом’яті та виконувати багато інших задач).
Псевдооператори мають таку загальну форму запиту:а

[] псевдооператор [][; коментар].

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

Псевдооператори визначення ідентифікаторів. Вони дозволяють виразу
присвоїти символічне ім’я, тобто ідентифікатор. В якості виразу може
бути константа, адреса, інше символічне ім’я. Після такої директиви цей
ідентифікатор можна використовувати в будь-якому місці де необхідно
вказати вираз. Два оператори:аEQU і =, ці псевдооператори подібні, але
між ними є істотна різниця:а

Позначені знаком “=” ідентифікатори можна перевизначати, а визначені
псевдооператором EQU неможна. Псевдооператор EQU можна використовувати
як з числовими такі з текстовими виразами, а псевдооператор “=” тільки з
числовими. Приклади:

К1аEQU 1024 – присвоєння імені константі; T_1аEQU DS:[BP][SI].
Комбінації адрес DS:[BP][SI] присвоюється символічне ім’я, всюди в
програмі замість комбінації цих адрес можна використовувати T_1. В_Т EQU
B_T1, визначення синоніму, тобто ім’я В_Т буде мати те ж значення як і
зміна В_Т1. REG1аEQU CX – присвоєння імені регістру. При використанні
псевдооператора “=” в якості виразу можуть виступати математичні
перетворення. В директиві EQU також можуть бути прості математичні
перетворення, вони будуть виконані асемблером під час трансляції.
Наприклад: CON1аEQU CON2*2 CONS1=24 CONS1=29 CONS1=CONS1+1.

Псевдооператори визначення даних. В асемблері можна використовувати
комірки пам’яті для збереження поіменованих даних, тобто змінних.
Найбільш використовуються такі псевдооператори для резервування
пам’яті:1) DB – Define Byte; 2) DW – Define Word; 3) DD – Define Double
Word; 4) DQ; 5) DF; 6) DT. В основному вони розрізняються по об’єму
пам’яті, який резервується. Псевдооператори визначення даних мають такий
формат запису: ім’я псевдооператор вираз [,……]. В якості виразу
найчастіше може бути константа. Псевдооператор DB резервує пам’ять
об’ємом 1 байт. DW – об’ємом одне слово. DD – подвійне слово. DQ –
2пподвійні слова. DF – 6 байт. DT – 10 байт. Наприклад змінна xyz DW 2S
– резервує для змінної ( ). Треба пам’ятати про макс. Vпмін. значення
даних, які можуть бути розміщені у відведеній пам’яті в кожному з цих
випадків, так наприклад: макс. значення байта без знака не може
перевищувати 255, макс. значення байта зі знаком 127, а мін. – 128.
Псевдооператори можна використовувати для створення в пам’яті таблиць,
наприклад: А_ТАВ DB 3, 2, 4, 6, 8, 0, 0, 0

DB 5, 4, 2, 1

Такий псевдооператор DB резервує в пам’яті місце для 12 значень
елементів таблиці А_ТАВ кожний розміром в байт. Можна вказувати довільну
кількість елементів таблиці рядку, важливо, щоб вони помістились в 132
позиції рядка. В асемблері є операція DUP, яка дозволяє скорочувати
задання таблиць у випадку однакових елементів. Даний псевдооператор
можна записати так:

А_ТАВ DB 3, 2, 4, 6, 8, 3 DUP (0),

DB 5, 4, 2, 1

В пам’яті можна резервувати пам’ять для змінної, але конкретного
значення їй не надавати. Для цього в полі виразу треба вказати знак
питання. Приклад: X_1аDB ? X_2 DW ?. Такі псевдооператори резервують в
пам’яті місце байту і слова, але початкового значення їм не надають.
X_1аi X_2 при цьому не будуть містити ніяких специфічних значень, навіть
(0). Можна зарезервувати в пам’яті місце для таблиці. Наприклад: А_ТАВ
DB 12 DUP (3) резервує місце для таблиці з 12 елементів. Можна в якості
значення змінної задавати рядок символів, для цього текст заключається в
апострофи.

Псевдооператори визначення сегменту і процедури. Для визначення сегменту
використовуються псевдооператори: SEGMENTаi ENDS. Це псевдооператори
ділять вихідну програму на сегменти. Вони відповідно відмічають початок
і кінець сегменту, але вини не повідомляють асемблер якого роду сегмент
повинен бути визначений. Для цього використовується псевдооператор
ASSUME, він має таку форму запису: ASSUME регістр сегмента: ім’я
сегмента [,…….]. це регістр сегмента – це ім’я одного із сегментних
регістрів CS, DS, SS, ES. Якщо П 80386 і вище то там ще буде FS, GS.
Ім’я сегмента це ім’я яке вказується в псевдооператорі SEGMENT. Цей
псевдооператор допомагає асемблеру перетворювати мітки в адреси, він
повідомляє, яким регістром хочете скористяватися при адресації міток.
Наприклад: ASSUME DS: DSEG – означає, якщо при трансляції програми буде
згадана мітка із сегмента DSEG, тобто регістр DS буде завжди вказувати
на початок сегмента DSEG. Майже завжди його поміщають після
псевдооператора SEGMENT. Зауважимо, що адресу початку сегменту потрібно
явно завантажити в DS. Псевдооператори PROG і ENDP визначають початок і
кінець процедури. Кожна процедура повинн0ппочинатись

Нашли опечатку? Выделите и нажмите CTRL+Enter

Похожие документы
Обсуждение

Ответить

Курсовые, Дипломы, Рефераты на заказ в кратчайшие сроки
Заказать реферат!
UkrReferat.com. Всі права захищені. 2000-2020