ВІКІСТОРІНКА
Навигация:
Інформатика
Історія
Автоматизація
Адміністрування
Антропологія
Архітектура
Біологія
Будівництво
Бухгалтерія
Військова наука
Виробництво
Географія
Геологія
Господарство
Демографія
Екологія
Економіка
Електроніка
Енергетика
Журналістика
Кінематографія
Комп'ютеризація
Креслення
Кулінарія
Культура
Культура
Лінгвістика
Література
Лексикологія
Логіка
Маркетинг
Математика
Медицина
Менеджмент
Металургія
Метрологія
Мистецтво
Музика
Наукознавство
Освіта
Охорона Праці
Підприємництво
Педагогіка
Поліграфія
Право
Приладобудування
Програмування
Психологія
Радіозв'язок
Релігія
Риторика
Соціологія
Спорт
Стандартизація
Статистика
Технології
Торгівля
Транспорт
Фізіологія
Фізика
Філософія
Фінанси
Фармакологія


Макровизначення і макрокоманди

 

Припустимо, що ми маємо два фрагменти програми:

Фрагмент 1: MOV AX, A ADD AX, B SUB AX, C Фрагмент 2: MOV AX, M ADD AX, N SUB AX, P

Якщо ввести формальні параметри ARG1, ARG2, ARG3, тоді можна написати одну узагальнену програму:

MOV AX, ARG1

ADD AX, ARG2

SUB AX, ARG3

Така узагальнена програма може бути оформлена у вигляді макровизначення.

Макровизначення – це записана за чітко визначеними правилами послідовність машинних команд Асемблера, якій присвоєно ім’я.

Загальний формат макровизначення:

Ім’я макровизначення MACRO [Список формальних параметрів]

Тіло макровизначення

ENDM

Для нашого прикладу макровизначення буде мати такий вигляд:

CALC MACRO ARG1, ARG2, ARG3

MOV AX, ARG1

ADD AX, ARG2

SUB AX, ARG3

ENDM

У тому місці програми, де повинна виконуватись послідовність ко­манд, яка розміщена у макровизначенні, записується макрокоманда. Її формат:

Ім’я макровизначення [Список фактичних параметрів]

Для нашої програми приклади макрокоманд:

CALC A, B, C

CALC M, N, P

Ім’я макрокоманди повинно збігатись з іменем макровизначення, до якого звертається макрокоманда.

У макрокоманді фактичні параметри записуються у тому самому порядку, в якому перераховані формальні параметри у відповідному макровизначенні.

У середині макровизначення може бути розташоване звернення до іншої макрокоманди, яка в цьому випадку носить назву вкладеної макрокоманди.

Під час трансляції програми макрокоманда заміняється командами з від­повідного макровизначення. Цей процес називається макророз­ши­ренням.

 

Приклад програми з використанням макровизначень

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

NAME MYPROG

KARETKA MACRO ARG ; Макровизначення для роботи з кареткою

MOV AH, 02h

MOV DL, ARG

INT 21h

ENDM

OUT_NUMB MACRO ; Макровизначення для виведення цифри

MOV AH, 06h

ADD AL, 48

MOV DL, AL

INT 21h

ENDM

OUT_STR MACRO ; Макровизначення для виведення рядка

MOV AH, 09h

INT 21h

ENDM

STACKSG SEGMENT STACK

DB 128 DUP(?) ; резервування пам’яті для стеку

STACKSG ENDS

DATE_SG SEGMENT

A DB 2

B DB 3

C DB 4

str0 DB "Data: A=2; B=3; C=4.$"

str1 DB "Rezult 1: Y = A+B+C = $"

str2 DB "Rezult 2: Y = A*B-C = $"

DATE_SG ENDS

CODE_SG SEGMENT

ASSUME CS:CODE_SG, DS:DATE_SG, SS:STACKSG

START PROC FAR

PUSH DS

SUB AX,AX

PUSH AX

MOV AX,DATE_SG

MOV DS,AX

CALL MAIN

RET

START ENDP

MAIN PROC

KARETKA 0Ah ; Переведення каретки

MOV DX, OFFSET str0

OUT_STR

KARETKA 0Ah ; Переведення каретки

KARETKA 0Dh ; Повернення каретки

MOV DX, OFFSET str1

OUT_STR

MOV AL, A

MOV BL, B

ADD AL, BL

ADD AL, C

OUT_NUMB

KARETKA 0Ah ; Переведення каретки

KARETKA 0Dh ; Повернення каретки

MOV DX, OFFSET str2

OUT_STR

MOV AL, A

CBW

IMUL B

SUB AL, C

OUT_NUMB

KARETKA 0Ah ; Переведення каретки

RET

MAIN ENDP

CODE_SG ENDS

END START

 

У наведеній програмі створено три макроси. Макрос OUT_NUMB використовується для виведення на екран однієї цифри, значення якої знаходиться у регістрі АL. Макрос OUT_STR призначений для виведення на екран рядка символів, причому перед викликом цього макросу необ­хідно занести в регістр DX адресу символьного рядка. Макрос KARETKA використовується для роботи з кареткою (переведення на новий рядок, повернення каретки на початок рядка). У ньому використовується параметр ARG, який дозволяє змінювати призначення цього макроса. Так, якщо значення аргументу дорівнюватиме 0Ah, то відбудеться переведення каретки на новий рядок, 0Dh – повернення каретки, 08h – переведення на один символ назад, 07h – подача звукового сигналу, тощо.

 

Проблема міток у макровизначеннях

 

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

Для запобігання дублювання міток вони описуються за допомогою директиви (оператора) LOCAL, наприклад:

LOCAL МЕТ1, МЕТ2

У цьому випадку транслятор замість вказаної мітки записує число, а при кожному зверненні до макровизначення це число збільшується на 1.

 

Циклічні макроси (директиви повторення)

 

Директиви повторення вимагають від асемблера повторити блок опе­раторів, що завершується директивою ENDM. Ці директиви не обов’язково повинні знаходитись в макровизначенні, але якщо вони там знаходяться, то одна директива ENDM потрібна для завершення блоку, який повто­рюється, а друга директива ENDM – для завершення макровизначення.

Директива REPT приводить до повторення блока операторів (команд або інших директив) до директиви ENDM у відповідності з кількістю повторень, вказаних у виразі

REPT вираз

Наприклад, якщо записати

REPT 3

INC CX

ENDM

то команда INC CX виконається тричі:

INC CX

INC CX

INC CX

За допомогою директиви IRP можна при кожному повторенні використовувати різні параметри:

IRP формальний параметр, <список>.

У списку параметри можуть бути символами, рядками, числовими або арифметичними константами.

Наприклад, якщо макрокомандою

PUSH_REGS <AX, BX, CX, DX>

викликається макровизначення

PUSH_REGS MACRO LIST

IRP REG, <LIST>

PUSH REG

ENDM

ENDM

це означатиме, що виконуються такі команди:

PUSH AX

PUSH BX

PUSH CX

PUSH DX

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

Якщо список параметрів містить символи, тоді можна застосувати директиву повторення IRPC, формат якої такий:

IRPC формальний параметр, рядок символів

Наприклад, якщо записати

IRPC CHAR, ABCD

ADD AX, CHAR&X

ENDM

то виконається така група команд

ADD AX, AX

ADD AX, BX

ADD AX, CX

ADD AX, DX

В даному прикладі використовується символ ”&” (амперсанд), який вказує асемблеру на необхідність конкатенації символів.

 

Умовні макроси (умовні директиви)

Виконання макровизначення може бути поставлено у залежність від виконання певних умов, що задаються директивою IFxx:

IFxx вираз умови

. . .

 

ELSE

. . .

 

ENDIF

Якщо задана умова виконується, то транслюються лише оператори, розташовані до директиви ELSE, у протилежному випадку – ті оператори, що записані після директиви ELSE.

У середині умови макровизначення можна використовувати також директиву EXITM, яка достроково завершує виконання макровизначення.

Так cамо, як і директиви повторення, умовні директиви не обов’язково повинні знаходитися у макровизначенні.

У таблиці 1 наведено перелік різних умовних директив.

Нижче наведено приклад умовної директиви, яка викликає макровизначення ERROR у випадку, коли опущено деякий параметр m:

IFB <m>

ERROR

EXITM

ENDIF

Як видно з цього прикладу, директива ELSE може бути відсутньою.

Таблиця 1 – Умовні директиви

Директива Умова виконання директиви
IF вираз Якщо вираз не дорівнює 0
IFE вираз Якщо вираз дорівнює 0
IFDEF ім’я Якщо ім’я визначено в програмі або об’явлено в директиві EXTRN
IFNDEF ім’я Якщо ім’я не визначено в програмі або не об’явлено в директиві EXTRN
IFB <arg> Якщо arg дорівнює пропуску (аргумент повинен бути взятий у кутові дужки)
IFNB <arg> Якщо arg не дорівнює пропуску (аргумент повинен бути взятий у кутові дужки)
IFIDN <arg1>, <arg2> Якщо рядки arg1 та arg2 збігаються (аргументи повинні бути взяті у кутові дужки)
IFDIF <arg1>, <arg2> Якщо рядки arg1 та arg2 не збігаються (аргументи повинні бути взяті у кутові дужки)
IF1 (немає виразу) Якщо виконується перший прохід транслятора
IF2 (немає виразу) Якщо виконується другий прохід транслятора

 

Використання макробібліотек

Найбільшої ефективності і зручності у роботі з макросами можна досягти лише при використанні макробібліотек.

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

Якщо файл макробібліотеки має ім’я MACRO.LIB, то для її підключення на початку програми слід використати таку директиву:

INCLUDE MACRO.LIB

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

Наприклад, якщо в наведеному вище прикладі вилучити макроси KARETKA, OUT_STR та OUT_NUMB і записати їх в окремий файл з іменем “MyLib.lib”, то в основній програмі замість текстів коду цих макросів слід написати лише одну директиву:

 

INCLUDE MyLib.lib.

 

© 2013 wikipage.com.ua - Дякуємо за посилання на wikipage.com.ua | Контакти