- •Системное программирование на макроассемблере masm32
- •«Системное программирование» (часть 1)
- •Вступление
- •1Организация среды исполнения для масм
- •1.1Цель работы
- •1.2 Теоретические сведения
- •If errorlevel 0 команда2
- •If errorlevel 0 goto метка
- •1.3Выполнение работы
- •1.4Состав отчета по работе
- •1.5Контрольные вопросы
- •2.2.2Состав пакета масм
- •2.2.3Центр масм – редактор Quick Editor
- •2.3Выполнение работы
- •2.4Состав отчета по работе
- •2.5Контрольные вопросы
- •3Высокоуровневый интерфейс языка масм
- •3.1Цель работы
- •3.2 Теоретические сведения
- •3.2.1Процедуры и макросы в ассемблере
- •3.2.2Синтаксис высокого уровня масм
- •3.2.3Макрос invoke
- •3.3Выполнение работы
- •4.2.2Потоки вывода и ввода
- •4.2.3Вывод и ввод в консольных приложениях
- •4.3Выполнение работы
- •4.4Состав отчета по работе
- •4.5Контрольные вопросы
- •5Ввод и вывод в ассемблерных приложениях с графическим интерфейсом
- •5.1Цель работы
- •5.2Теоретические сведения
- •5.3Выполнение работы
- •6.3.1Фрейм кода (области 1-5)
- •6.3.2Фрейм дампа памяти (области 9,10 и 11)
- •6.3.3Фрейм регистров процессора (области 6, 7 и 8)
- •6.3.4Фрейм стека (области 12, 13 и 14)
- •6.4Выполнение работы
- •6.5Состав отчета по работе
- •6.6Контрольные вопросы
- •Приложение а Префиксы «венгерской» нотации типов данных WinApi
- •Рекомендованная литература
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 имеет столь большое применение.