Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2012- СИСПРОГ на МАСМ.doc
Скачиваний:
21
Добавлен:
09.11.2019
Размер:
553.47 Кб
Скачать

3.2.1Процедуры и макросы в ассемблере

Понятие процедур и функций (П и Ф) вам должно быть хорошо знакомо по базовому курсу программирования.

Напомним, что в программировании процедура – это именованный участок кода программы, который можно вызывать по его имени. Вызов процедуры синтаксически выглядит как обычный оператор. Вызов процедуры порождает в стеке программы кадр параметров процедуры, который освобождается после ее завершения, управление при этом передается оператору, следующему за операторов вызова процедуры.

Функция — это специализированный вариант процедуры. Всё, сказанное выше про процедуры, справедливо и для функций. Но функция пишется так, чтобы в точку вызова обязательно возвращать некоторое одиночное значение. Поэтому вызов функции выглядит как операнд правой части оператора присваивания или как параметр другого вызова. При завершении выполнения функции в точке ее вызова остается возвращаемое значение и продолжается выполнение оператора, в который был включен вызов функции.

Вызовы П и Ф (равно как и возвраты из них) поддерживаются аппаратно процессором в период исполнения программы (рантайм период).

Замечания о терминологии. Сказанное выше о П и Ф относится не к конкретном языку программирования, а, скорее, к общетеоретическим представлениям об этих алгоритмических абстракциях. В языке Паскаль представление о П и Ф наиболее близко к описанному теоретическому, в Си нет понятия «процедура», но зато есть возможность вызывать функции «по-процедурному», записывая их как оператор. Во всех ассемблерах, напротив, нет понятия «функция», синтаксически описываются только процедуры. Но зато всегда есть возможность организовать возвращаемое значение из процедуры, и традиционно это делается через регистр EAX. Поэтому в дальнейшем, при анализе исходных ассемблерных текстов программ всякое упоминание терминов «процедура» или «функция» подразумевает на самом деле вызов ассемблерных процедур и ничего иного.

Совсем другой сущностью являются ассемблерные макросы.

Они были придуманы программистами для облегчения повторного написания больших и/или сложных участков исходного текста программ. Так что можно определить макрос как именованный участок текста программы («тело» макроса) , который можно вставлять в текст «вызывающей его» программы, упоминая его имя. Тогда имя макроса в программе заменяется его телом, и это действие называют макрорасширением. Таким образом, при ручном написании программы разработчик за счет макросов здорово экономит усилия, но после всех макрорасширений текст программы имеет объем, больший , нежели тот, что программист написал своими руками.

Из сказанного понятно, что вся работа с макросами происходит на этапах написания исходного текста (определение макросов и вставка их «вызовов» в нужные места программы) и компиляции (именно тут компилятор сначала выполняет макрорасширения, а потом полученный текст компилирует в объектный машинный код).

Сила макропрограммирования состоит в том, что по сути применение макросов означает замену маленьких текстов на большие тексты. Никакого контроля типов тут не производится. Это же относится и к передаче параметров в макросы.

Рассмотрим простейший пример. Архитектура процессора не позволяет производить прямое присваивание значения одной переменной памяти другой переменной. То есть оператор mov Var1, Var2 (по смыслу это Var1 = Var2;) компилятором опознается как ошибочный. Обход этого неудобства прост. Определим макрос

m2m MACRO M1, M2 ; заголовок макроса

push M2 ;; тело макроса

pop M1

ENDM ; завершитель макроса

И если его вызов имеет вид m2m Var1, Var2, то в текст программы вместо него буде вставлено:

push Var2

pop Var1

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

Замечание о комментариях. При макрорасширениях в текст программы вставляется всё, что содержится в теле макроса, в том числе и комментарии (они начинаются с символа «;» и идут до конца строки). Но, если комментарий начинается с «;;», то он в макрорасширение не переносится.

«Вызовы» макросов выглядят похоже на вызовы процедур в Паскале:

CallModalDialog hInstance,0,dlgproc,NULL

Но обратите внимание, что после имени макроса CallModalDialog список передаваемых ему параметров в скобки не заключается.

«Вызовы» макросов, строго говоря, вызовами не являются, хотя так и говорят. Правильнее считать такие записи «точками вставки» тел макросов. Термин «вызов» точно относится к П и Ф, но не к макросам.