Програмування в машинних кодах та мовою асемблера. Основні директиви асемблера

Мітки
Мітка в мові асемблера може містити такі символи:


Літери: від A до Z та від a до z
Цифри: від 0 до 9
Спецсимволи: знак питання (?)
точка (.) (тільки перший символ)
знак "комерційне ет" (@)
підкреслення (_)
долар ($)

Першим символом у мітці має бути буква або спецсимвол. Цифра може бути першим символом мітки, а символи $ і? іноді мають спеціальні значення та зазвичай не рекомендуються до використання. Великі та маленькі літери за замовчуванням не розрізняються, але відмінність можна включити, задавши ту чи іншу опцію командному рядкуасемблера. Максимальна довжинаетикетці - 31 символ. Приклади тегів: COUNT, PAGE25, $E10. Рекомендується використовувати описові та смислові мітки. Імена регістрів, наприклад, AX, DI або AL є зарезервованими та використовуються лише для вказівки відповідних регістрів.
Якщо мітка розташовується перед командою процесора, відразу після неї завжди ставиться символ «:» (двокрапка), який вказує асемблеру, що треба створити змінну з цим ім'ям, що містить адресу поточної команди:
some_loop:

loopne some_loop
Коли мітка стоїть перед директивою асемблера, вона зазвичай виявляється одним із операндів цієї директиви і двокрапка не ставиться:

codesg segment
lodsw; рахувати слово з рядка,
cmp ax,7; якщо це 7 - вийти з циклу
codesg ends
Розглянемо директиви, що працюють безпосередньо з мітками та їх значеннями: LABEL, EQU та =.

Директива LABEL

Мітка label тип Директива LABEL визначає мітку та задає її тип. Тип може бути одним з: BYTE (байт), WORD (слово), DWORD (подвійне слово), FWORD (6 байт), QWORD (учетверенное слово), TBYTE (10 байт), NEAR (ближня мітка), FAR (дальня мітка) ). Мітка отримує значення, що дорівнює адресі наступної команди або таких даних, і тип, вказаний явно. Залежно від типу команда
mov мітка,0 запише на згадку про байт (слово, подвійне слово і т.д.), заповнений нулями, а команда
call мітка здійснить ближній або дальній виклик підпрограми.

За допомогою директиви LABEL зручно організовувати доступ до тих самих даних, як до байтів, так і до слів, визначивши перед даними дві мітки з різними типами.

Директива EQU

Директива EQU надає мітці значення, що визначається як результат цілісного виразу у правій частині. Результатом цього виразу може бути ціле число, адреса або будь-який рядок символів:
equ вираз

truth equ 1
message1 equ "Try again$"
var2 equ 4
cmp ax, truth; cmp ax,1
db message1; db "Try again$"
mov ax, var2; mov ax, 4 Директива EQU найчастіше використовується для введення параметрів, загальних для всієї програми, аналогічно команді #define препроцесора мови С.

Директива =

Директива = еквівалентна EQU, але мітка, що нею визначається, може приймати тільки цілочисельні значення. Крім того, мітка, зазначена цією директивою, може бути перевизначена.

Кожен асемблер пропонує цілий набір спеціальних визначених міток - це може бути Поточна дата(@date або??date), тип процесора (@cpu) або ім'я того чи іншого сегмента програми, але єдина зумовлена ​​мітка, що підтримується всіма асемблерами, що розглядаються нами, - $ . Вона завжди відповідає поточній адресі. Наприклад, команда

Jmp $

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

Щоб краще зрозуміти цю справу я написав маленьку програму. Все той же “Hello World”, але на новий лад:) Текст нижче:

Програ ассемблируется TASM і MASM, але EXE файлик, асемблированный MASM однією байт більше. Помічаємо, що команду mov dx,offset msg, замінили на команду lea dx,msgb. LEA поміщає адресу зміщення зазначених даних DX, тобто. робить те ж саме, що і команда mov з offset. Рекомендую це подивитись під відладчиком.



Дивимося уважно лістинги асемблювання та знаходимо різницю.



Цікаво, що TASM асемблював команду LEA в даному випадкуяк команду MOV (код операції BA), а MASM асемблював команду LEA в інший код операції - 8D16, що збільшило розмір програми на 1 байт. Чому він вирішив так зробити, поки не знаю, але цікаво було б з'ясувати.

Одним з найважливіших елементівцій частині книги є приклади програм в машинних кодахта мовою АССЕМБЛЕРа. У роздруках цих програм нам доведеться вживати так

звані ДИРЕКТИВИ АСЕМБЛЕРА і зараз, напевно, саме зручний часдля того, щоб дати уявлення про те, що це таке.

Ми розглянемо такі директиви: ORG, EQU, DEFB, DEFW, DEFM та END, але перш ніж почати їх розгляд, треба твердо для себе зрозуміти:

1. Директиви АССЕМБЛЕРа є командами процесора Z8 0 й у сенсі ставлення до машинного коду Z8 0 немає.

2. АССЕМБЛЕР - це програма, яка перекладає (транслює) текст, написаний Вами як мнемонік в об'єктний код, що є машинним. І ці директиви АССЕМБЛЕРА - це деякі команди, що асемблює програмі. Вони не транслюються і в об'єктний код не увійдуть, але спростять Вам написання, і найголовніше читання програми, записаної в мнемоніках.

3. Програм-АССЕМБЛЕР існує велика кількість і кожна з них може мати свої власні директиви. Вони можуть мати однакові директиви, але пред'являти різні вимоги до їх вживання. Одним словом, саме способи використання директив АССЕМБЛЕР Вам необхідно встановлювати за інструкцією до асембліруючої програми, якою Ви користуєтеся (напр. EDITAS, GENS 3, GENS 4, ZEUS і т.п.). І хоча стандартів не існує, проте деякі основні поняття все ж таки виділити можна, ось на них ми і зупинимося.

3.1. Коментарі.

Ми почнемо з найпростішого – з коментарів. Вони записуються після символу ";" (крапка з комою) .

Вам, звичайно, зрозуміло, що все, що є коментарями, АССЕМБЛЕР в машинний код не компілюється - це ні до чого. Вони служать тільки для того, щоб Вам було зручніше розбиратися з лістингом, який склав хтось інший або Ви самі, але давним-давно.

Наприклад:

10 60001 LD E,A 2 0

Як бачите, рядок може

; Завантажили в регістр E содер-; акумулятора. ; Зменшили його на одиницю.

остояти лише з коментаря.

Мітки.

Мітки значно спрощують написання програм у мнемоніках АССЕМБЛЕРА. В операціях переходу JP, JR, DJNZ, виклику підпрограм CALL Ви можете не вказувати адресу, в яку Ви хочете зробити перехід, а замість нього підставити мітку. З іншого боку, коли писатимете команди для цієї адреси, підставте мітку і там, Наприклад:

10 60001 BEGIN LD B,0 4

20 60003 AGAIN INC HL

40 60005 DJNZ, AGAIN

3.2.

250 260 270

60110 60111 60113

LD A,(HL) CP 80H JR NZ,BEGIN

Як бачите, дуже зручно. Відразу видно, що з рядка 40 повернення здійснюється до мітки AGAIN, якщо регістр B не досягнув нуля. З рядка 270 повернення здійснюється до мітки BEGIN.

Виразно має сенс вибирати для мітки таке ім'я, яке відповідало б сенсу операції, що виконується - це полегшує читання і розуміння лістингу програми.

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

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

Наприклад, Вам у Вашій програмі неодноразово доводиться викликати процедури ПЗП, скажімо CLEAR (1EACH=7 8 52) та OUT-LINE (1856H=6230). Тоді на початку Вашої програми Ви задаєте

наприклад, назвавши їх CLEAR

директивою

значення своїм міткам, н

та OUT L.

CLEAR

EQU 7 8 52

OUT L

EQU 62 3 0

LABEL

EQU 60016

виклик

вали ці

процедури або

за міткою.

60001

LD HL, (LABEL)

60004

LD BC, 0008

60007

LD DE, (04 52)

60010

CALL CLEAR

60013

CALL OUT L

60016

Відразу

повинні Вас

попередити,

приклади

з точки зору

програмною

приклади того, як використовуються ті чи інші директиви АССЕМБЛЕР і якщо Вам потрібен у прикладах реальний сенс, то Ви його отримаєте трохи пізніше, у наступних розділах, де ми розбиратимемо практичні прийомипрограмування.

Давайте ще раз подивимося на попередній приклад. У рядку 30 ми надсилаємо в реєстрову пару HL те, що міститься в адресі, на яку вказує мітка LABEL, а вона, згідно з директивою EQU, вказує на адресу 60016.

Отже, у осередках 60016 та 60017 містяться деякі дані, які згодом можуть використовуватися програмою. Ці дані Ви можете надіслати в осередки самі перед компіляцією. І не треба для цього залучати машинний код. Початкові значенняу осередках пам'яті Ви можете виставити за допомогою директив DEFB, DEFW та DEFM.

DEFB – DEFINE BYTE – задати байт.

DEFW - DEFINE WORD - задати "слово" ("слово" - це два послідовно розташованих байти. Зазвичай це адреса.) DEFM - DEFINE MESSAGE - задати повідомлення (це кілька байтів, що підходять) . Зазвичай ассемблирующие програми накладають обмеження те що, скільки байтів можна задати однієї директивою DEFM, скажімо трохи більше п'яти. Але вас це не повинно хвилювати. Якщо Ви хочете задати довге повідомлення, то можете ставити поспіль стільки DEFM рядків, скільки хочете.

Отже, DEFB задає один одиночний байт (0...255) , DEFW -два байта, що йдуть поспіль (0...65535), а DEFM - групу байтів, що йдуть поспіль - текстове повідомлення, числова таблицяі т.п.

У нашому попередньому прикладі, якщо ми хочемо зберігати в адресі 60016 та 60017 деяке двобайтне число, рядок 80 слід записати, наприклад так:

80 60016 DEFW 5C92H

90 60018

Припустимо, Ви хочете, починаючи з адреси 60135, зберігати слово "Spectrum".

Код букви "S" Код букви "p" "e" "c" "t" "r"

"u" "m"

60135

60136

60137

60138

60139

60140

60141

60142

53H 7 0H 65H 63H 7 4H 72H 75H 6DH

DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB

можете його задати парами байтів:

Але простіше і правильніше поставити його як повідомлення:

60135 DEFM 5370656374; "Spect"

60140 DEFM 72756D; "rum"

Є особливий випадокпри програмуванні на АССЕМБЛЕРі, коли текст програми також доводиться вводити через DEFB чи DEFM. Це випадок, коли ви пишете програму для вбудованого калькулятора. Адже програма, що асемблює, може перевести в машинний код мнемоніки АССЕМБЛЕРа, але вона нічого не знає про коди калькулятора і не знає його мнемонік. Код калькулятора - це внутрішня "Синклерівська" справа, його інтерпретацією

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

Ми з Вами в першій частині книги використовували мнемонічні позначення команд калькулятора, типу add, stk_data s_lt і т. п., і писали їх з невеликої літери на відміну від команд процесора. Але робили це раніше і робитимемо надалі тільки заради розуміння та зручності запису. Програма-АССЕМБЛЕР таких мнемонік не знає, їх немає у її словнику.

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

графіку, а також такі кодові послідовності, що асембуюча програма не розуміє, як команди АССЕМБЛЕРа.

3.5. Директиви ORG, END.

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

Ви звернули увагу на те, що у наведених вище прикладах ми зліва писали стовпець адрес, в яких будуть розміщуватися ті чи інші команди. Так от цього при програмуванні на АСЕМБЛЕРі робити не треба. Достатньо на початку дати директиву

10 ORG 63000

і далі ассемблирующая програма сама розрахує у якому осередку пам'яті перебуватиме та чи інша команда. Це дуже полегшує процес програмування. А якщо Ви внесете зміни до готового тексту, АССЕМБЛЕР сам підправить усі адреси.

Директива END вказує на кінець програми. Якщо після нього щось і стоятиме, то АССЕМБЛЕР при компіляції це проігнорує.

Ось мабуть і все, що для початку варто знати про директиви Ассемблера. Це не всі директиви, які можуть зустрітися в житті, та й правила їх використання для різних АССЕМБЛЕР - різні, але за великим рахунком цей мінімум задовольнить 90 відсотків Ваших потреб в інформації, а решту Ви повинні почерпнути з інструкції до того АССЕМБЛЕР, з яким працюєте .

При написанні програм на мові Асемблер використовуються директиви, які вказують компілятору положення програми в пам'яті, визначають макроси, ініціалізують пам'ять та ін. Список директив та їх опис наведено у табл. 1.8. Запис усіх директив починається з точки. Коротко перерахуємо функції, що виконуються директивами, в кожному з сегментів.

Сегмент програми відкривається директивою CSEG. Якщо програма починається з цього сегмента, директива може бути відсутня. У сегменті програми за допомогою директиви ORG можна вказати початок сегмента.

Директива.DB в сегменті визначає один байт або групу байтів, констант, що записуються у Flash-пам'ять. Директива DW визначає слово або групу слів, що записуються в пам'ять як констант. Початок запису констант визначається міткою, що стоїть перед відповідною директивою. Перераховані константи поділяються комами.

Директива.DEF надає регістру символічне ім'я. Директиви .EQU, .SET надають значення імені. Ім'я, якому присвоєно значення директивою. EQU, не може бути переназначено, і значення не може бути змінено. Ім'я, надане директивою.SET, може бути змінене іншою директивою.SET.

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

Директива INCLUDE з ім'ям файлу використовується для включення в текст програми іншого файлу.

Таблиця 1.8. Список директив

Директива

Опис

Резервувати байти в ОЗУ

Сегмент програми

Визначити байт - константу у Flash-пам'яті або

Призначити регістру символічне ім'я

Визначає пристрій, для якого компілюється

програма

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

Визначає слово у Flash-пам'яті або EEPROM

Кінець макросу

Встановити постійний вираз

Сегмент EEPROM

Вихід із файлу

Вкласти інший файл

Включити генерацію лістингу

Включити розгортання макросів у лістингу

Початок макросу

Вимкнути генерацію лістингу

Встановити положення у сегменті

Встановити для змінної еквівалентний вираз

Директиви.MACRO та.ENDMACRO обрамляють макровизначення. Макровизначення може мати до 10 параметрів з фіксованими іменами@ 0, ..., @ 9. При виклику макровизначення параметри задають у вигляді списку у порядку нумерації.

Сегмент даних починається директивою. У сегменті можуть бути використані директиви .ORG та .BYTE. Директива.BYTE визначає кількість байтів, до яких буде здійснюватися звернення під час виконання програми. Область, що резервується, починається за адресою, що визначається міткою перед директивою.

Сегмент типу EEPROM починається директивою ESEG. У сегменті можуть бути використані директиви .ORG, .DB, .DW. Директива .DB в сегменті визначає один або групу байтів, що записуються в EEPROM. Директива DW визначає слово або групу слів, що записуються в пам'ять EEPROM парами по 2 байти. Початок запису байтів і слів визначається міткою, що стоїть перед директивою.

Директиви .LIST, .NOLIST, .LISTMAC використовують для керування виведенням лістингу.

Директиви є команди управління компілятором. Оголошення кожної з них має розпочинатися з точки. Практика показує, що у будь-якому асемблері найінтенсивніше використовується лише близько 10…20 директив. Всі інші або є обов'язковими, або відповідають за управління, лише незначними властивостями компілятора. До "основним", характерним і для асемблерів інших процесорів, відносяться директиви .equ, .org, .def, .сseg, .dseg і т.д. Ну, а такі директиви, як .dq, .exit, .listmac реальних програмахзустрічаються справді дуже рідко. Нижче наведено перелік, опис та приклади використання директив фірмового асемблера мікроконтролерів AVR.

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

Директива.
Синтаксис написання:
.include "(шлях до файлу)"
Приклад використання:

Include "m8def.inc" ;вставка стандартного файлу заголовка

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

Директива.
Синтаксис написання:
.exit
Приклад використання:

Exit ;кінець файлу

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

Директиви.
Синтаксис написання:
.nolist, .list
Приклад використання:

Nolist ;заборонити виведення тексту файлу “m8def.inc” .include "m8def.inc" ;у файл листингу програми.list ;продовжити виведення інформації

Директива.equ надає символьному імені деяке числове значення. Символьне ім'я має бути унікальним і не може бути змінено у процесі написання програми. Директива не може застосовуватися для призначення символьних імен регістрам загального призначення.

Директива.equ
Синтаксис написання:
.equ (символьне ім'я) = (вираз)
Приклад використання:

Equ DDRB = 0x17 ;присвоєння імені DDRB значення 0x17 .equ PORTB = DDRB + 1 ;присвоєння імені PORTB значення 0x18

Директива.set справляє те саме дію, що и.equ. Але на відміну від останньої символьне ім'я може бути перевизначено в будь-якому місці програми.

Директива.
Синтаксис написання:
.set (символьне ім'я) = (вираз)
Приклад використання:

Set OFFSET = 0x100; присвоєння імені OFFSET значення 0x100.

.set OFFSET = OFFSET + 1 ;перевизначення значення OFFSET Директива.def надає символьне ім'я одному з регістрів загального призначення. Надалі ході програмице ім'я

може бути скасовано директивою.
Синтаксис написання:
Директиви.def, .undef
.def (символьне ім'я) = (реєстр)
Приклад використання:

.undef (символьне ім'я)

Директиви .db, .dw, .dd, .dq призначені для резервування пам'яті мікроконтролера під ініціалізовані дані. Усі вони можуть застосовуватися лише в сегментах коду та EEPROM-пам'яті. Різниця між цими директивами полягає в розрядності даних. Директива.db резервує байти, .dw – слова, .dd – подвійні слова. У поодиноких випадках може виявитися зручним використання директиви.dq, що резервує 64-розрядні дані.

Директиви .db, .dw, .dd, .dq
Синтаксис написання:
(мітка): .db (8-розрядні дані)
(мітка): .dw (16-розрядні дані)
(мітка): .dd (32-розрядні дані)
(мітка): .dq (64-розрядні дані)
Приклад використання:

Label: .db 0xFA, 250, -6, 0b11111010 .dw 0xFADE, 64222, -1314, 0b1111101011011110 8077149609196178927, -521103510453211

Директива.byte резервує пам'ять під неініціалізовані дані у сегментах SRAM та EEPROM.

Директива.byte
Синтаксис написання:
(мітка): .byte (кількість даних, що резервуються)
Приклад використання:

Equ PAGESIZE = 0x20 buffer: . byte 2*PAGESIZE ;резервування 64 байт у SRAM

Директиви .dseg, .eseg, .cseg визначають початок сегментів даних, EEPROM-пам'яті та коду відповідно. У вихідному файлікожен із сегментів може бути представлений тільки в одному екземплярі. Якщо всі ці директиви відсутні в програмі, компілятор за умовчанням вважає, що всі оператори розташовані в секції коду.

Директиви.dseg, .eseg, .cseg
Синтаксис написання:
.dseg
.eseg
.cseg
Приклад використання:

Dseg ;початок сегмента даних buffer: . byte 32; резервування 32 байт під буфер в SRAM. cseg; початок сегмента коду rjmp initial. string: .db "ATmega8", 0; рядок, що зберігається у FLASH-пам'яті. = 0xAA

Директива.org дозволяє встановити компілятор початкову адресу в межах сегментів коду, даних та EEPROM-пам'яті. У разі застосування в сегменті коду директива визначає адресу розміщення 16-розрядного слова програм.

Директива.org
Синтаксис написання:
.org (початкова адреса)
Приклад використання:

Equ SRAM_START = 0x60 .equ RAMEND = 0x045F .dseg ;початок сегмента даних.org SRAM_START ;резервування 32 байт у SRAM під буфер, buffer: . byte 32 ;починаючи з адреси 0x60 .cseg ;початок сегмента коду.org 0 ;вектор скидання за адресою 0 rjmp initial .

Директиви .macro, .endmacro (.endm), що визначають початок та кінець макросу відповідно.

Директиви.macro, .endmacro (.endm)
Синтаксис написання:
.macro (ім'я макросу)
Приклад використання:

Macro set_bit ; оголошення макросу установки біта порту sbi @ 0, @ 1; встановити біт @ 1 регістра порту @ 0 sbi @ 0-1, @ 1; настроїти на виведення лінію @ 1 регістра DDRx. Endm.

set_bit PORTB,0; встановити на лінії 0 порту B лог.1

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

.listmac

Listmac ;дозволити розгортати текст макросів у файлі лістингу Директиви.message, .warning, .error призначені для виведення у вікно збирання проектудодаткової інформації

про хід компіляції програми. Директива.message генерує повідомлення для рядка, в якому було зустрінуто її виклик. Застосування.warning призводить до попередження, а.error – до повідомлення про помилку. В останньому випадку збирання проекту припиняється.
Синтаксис написання:
Директиви.message, .warning, .error
.message "(текст повідомлення)"
.warning "(текст попередження)"
Приклад використання:

.error "(текст повідомлення про помилку)"

Message "Macros має бути названий тут." .warning "Too high frequency!" .error "Wrong macro argument!" Група директив умовної компіляції .ifdef, .ifndef, .if, .else, elif, .endif використовуються для вставокпрограмного коду залежно відрізних умов

. Директива.ifdef перевіряють наявність оголошення певного символьного імені. За директивою може йти набір команд, які будуть підставлені в текст, якщо умова перевірки “істина” (ім'я було оголошено). Директива.ifndef протилежна.ifdef перевіряє відсутність оголошення символьного імені. Директива.if здійснює підстановку коду, коли виконується умова порівняння, зазначена як її параметр. Команди, які повинні виконуватися, якщо умова директиви.if "хибно" - розташовуються після директиви.else. Розгалуження типу "якщо" - "то" може мати кілька рівнів вкладення завдяки директиві. elif. Кожен блок перевірки, що починається з .ifdef, .ifndef, .if, має бути закритий директивою .endif.
Синтаксис написання:
Директиви if, .ifdef, .ifndef, .else, elif, .endif
.ifdef (символ) (або.ifndef (символ))
.if (умова)
.else (вираз) (або.elif (умова))
Приклад використання:

Macro del_ms ;макрос, що формує затримку часу в мс.ifndef FREQ ;якщо не оголошено константу FREQ (частота в Гц), .warning "Undefined FREQ constan!" ;видаємо попередження и.equ FREQ = 1000000 ;присвоюємо за замовчуванням значення 1 МГц.endif .equ DELAY = (@0*FREQ)/4000 ;величина завдання затримки часу.if DELAY > 65535 ;якщо DELAY розміром, якщо DELAY розміром, то. error “Integer overflow in DELAY!” ;реалізація макросу не можлива. pop XL; відновлюємо з стека робочі регістри XH, XL. Endif. Endm. .equ FREQ = 2000000; оголошеннятактової частоти

2 МГц. del_ms 25; формування затримки часу в 25 мс

Асемблери MASM, TASM та WASM відрізняються між собою. Однак створення простих програм для них практично не має відмінностей, за винятком самого асемблювання та компонування. Отже, наша перша програма для MASM, TASM та WASM, яка виводитьанглійську букву "A" в поточній позиції курсору, тобто в лівомуверхньому кутку

екрану: Model tiny .code ORG 100h start: MOV AH,2 MOV DL,41h INT 21h INT 20h END start Цей текст можна набрати в будь-якому простомутекстовому редакторі

– наприклад, у БЛОКНОТІ (NotePad) від WINDOWS (але не в Word і не в іншому «навороченому»). Однак я рекомендую «просунутий» текстовий редактор із підсвічуванням синтаксису, наприклад, PSPad (див. розділ ). Потім зберігаємо цей файл із розширенням.asm, наприклад, у папці MYPROG. Назвемо файл atest. Отже, ми отримали: C:\MYPROG\atest.asm.
ПРИМІТКА

Зверніть увагу, що у першій команді ми записали 2 замість 02h. MASM, TASM та WASM, як і Emu8086, допускають такі «вільності». Хоча можна написати 02h – помилок не буде.:

Пояснення до програми.model tiny - Перший рядок. Директива.model визначає модель пам'яті конкретного типу файлів. У нашому випадку це файл зрозширенням COM

Тому вибираємо модель tiny, в якій об'єднані сегменти коду, даних і стека. Модель tiny призначена для створення файлів типу СОМ..code

- Другий рядок. Ця директива починає сегмент коду. ORG 100h - третій рядок. Ця команда встановлює значення програмного лічильника в 100h, тому що при завантаженні СОМ-файлу на згадку, DOS виділяє під блок даних PSP перші 256 байт (десяткове число

start: MOV AH, 02h- 4-й рядок. Мітка start розташовується перед першою командою в програмі і використовуватиметься в директиві END, щоб вказати, з якої команди починається програма. Інструкція MOV поміщає значення другого операнда першого операнд. Тобто значення 02h міститься в регістр АН. Навіщо це робиться? 02h - це функція ДОСа, яка виводить символ на екран. Ми пишемо програму для DOS, тому використовуємо команди цієї операційної системи(ОС). А записуємо ми цю функцію (а точніше її номер) саме в регістр АН, тому що переривання 21h використовує саме цей регістр.

MOV DL, 41h- 5-й рядок. Код символу "A" заноситься в регістр DL. Код символу A за стандартом ASCII – це число 41h.

INT 21h- 6-й рядок. Це і є те саме переривання 21h – команда, що викликає системну функцію DOS, задану в регістрі АН (у прикладі це функція 02h). Команда INT 21h – основний засіб взаємодії програм із ОС.

INT 20h- 7-й рядок. Це переривання, яке повідомляє операційну систему про вихід із програми, і про передачу управління консольному додатку. У тому випадку, якщо програма вже відкомпільована та запущена з ОС, команда INT 20h поверне нас до ОС (наприклад, до DOS).

END start- 8-й рядок. Директива END завершує програму, одночасно вказуючи, з якої мітки має починатися її виконання.