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

3.2.2Синтаксис высокого уровня масм

Начнем с того, что для самостоятельного изучения макроязыка следует читать файл \MASM32\help\masm32.chm, раздел «MACRO Reference». Здесь же дадим только беглое описание его.

MASM имеет ряд встроенных операторов, которые позволяют программистам использовать C-подобные конструкции для проверки условий и организации циклов при написании программ, код которых взаимодействует с ОС Windows. Когда компилятор ML.EX обрабатывает такие операторы, то создаетя весьма эффективный код. Если использование, к примеру, оператора .IF сравнить в «голыми» операторами типа «cmp reg, var» и «jne label», то последние выглядят, образно говоря, «ночными кошмарами» с точки зрения отслеживания количества переходов и придумывания необходимых меток, и они, кстати, в итоге ни быстрее, ни компактнее.

.if uMsg == WM_COMMAND

;code

.elseif uMsg == WM_PAINT

;code

.elseif uMsg == WM_CLOSE

и т.д. ....

При проверках условий используются символы: == равно, != не равно, > больше, >= больше или равно, < меньше, <= меньше или раавно, & побитовая проверка (формат: выражение & битовая маска, т.е. число), ! логическое «не», && логическое «и», || логическое «или», CARRY? проверка флага переноса Carry, OVERFLOW? проверка флага переполнения Оverflow, PARITY? проверка флага четности Parity, SIGN? проверка флага знака Sign, ZERO? проверка флага нуля Zero.

Инструкции макроциклов используют слова FOR, WHILE и REPEAT.

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

Есть возможность создавать макросы, которые по синтаксису вызова похожи на процедуры и, кроме этого, можно создавать макрофункции, способные возвращать значения. В макросах можно создавать локальные метки и переменные.

3.2.3Макрос invoke

В программировании чрезвычайно часто приходится вызывать процедуры (подпрограммы). Важность и масштабность применения этого действия переоценить просто невозможно. Поэтому важно иметь прозрачный, чёткий, надежно компилируемый синтаксис для этого действия. Процедуры, как правило, имеют параметры. Параметры передаются процедуре через стек командой push параметр. Список параметров определяется при написании процедуры в ее заголовке:

dlgproc proc Win:DWORD , uMsg:DWORD, wParam:DWORD, Param:DWORD

Чтобы реализовать вызов такой процедуры, «крутой» программист-ассемлерщик вручную напишет следующее:

Push NULL

Push nParam

Push offset szInvitation

Push hDialog2

CALL dlgproc

Add esp, 16

И, разумеется, нельзя ошибаться ни в количестве параметров, ни в их типе, ни в порядке их перечисления, ни в их написании. И забота о корректной очистке стека ложится также на автора таких строк. В случае любой из перечисленных ошибок этот код будет откомпилирован (да-да!), но вызовет сбой при исполнении.

Программист с реальным взглядом на вещи, не отягощенный ЧСВ (см. http://lurkmore.to/ЧСВ), разместит в начале своей программы так называемый прототип процедуры:

dlgproc PROTO :DWORD,:DWORD,:DWORD,:DWORD

и там, где требуется по логике, запишет вызов:

invoke dlgproc, hDialog2, ADDR szInvitation, nParam, NULL

Выгоды, которые реалист получит при этом, следующие:

  • компилятор проверит количество и типы фактических параметров на соответствие прототипу, а прототип – на соответствие заголовку процедуры; если что-то будет не так, последует сообщение об ошибке компиляции в этом месте;

  • порядок перечисления параметров в invoke такой же, как в заголовке процедуры (воспроизводить такой же порядок надежнее, чем аккуратно выстраивать обратный порядок команд push при ручном программировании);

  • очистка стека после завершения процедуры будет запрограммирована компилятором автоматически.

Отсюда понятно, почему макрос invoke имеет столь большое применение.