Лабораторная работа № 5
ПРИЛОЖЕНИЯ НА ЯЗЫКЕ АССЕМБЛЕР В СРЕДЕ WINDOWS
1 Цель работы
Научиться создавать программы на языке ассемблер, использующие вызовы функций Win32 API. Изучить технологию создания оконных приложений
2 Программирование на ассемблер в ОС Windows
2.1 Ассемблер и Win32
Программирование на ассемблере под Win32 воспринимается весьма не однозначно. Считается, что написание приложений слишком сложно для применения ассемблера.
В отличие от программирования под DOS, где программы написанные на языках высокого уровня были мало похожи на свои аналоги, написанные на ассемблере, приложения под Win32 имеют гораздо больше общего. В первую очередь, это связано с тем, что обращение к сервису операционной системы в Windows осуществляется посредством вызова функций, а не прерываний, что было характерно для DOS. Здесь нет передачи параметров в регистрах при обращении к сервисным функциям и, соответственно, нет и множества результирующих значений возвращаемых в регистрах общего назначения и регистре флагов. Следовательно проще запомнить и использовать протоколы вызова функций системного сервиса. С другой стороны, в Win32 нельзя непосредственно работать на аппаратном уровне, как в DOS. Вообще написание программ под Win32 стало значительно проще и это обусловлено следующими факторами:
отсутствие startup кода, характерного для приложений и динамических библиотек написанных под Windows 3.x;
гибкая система адресации к памяти: возможность обращаться к памяти через любой регистр общего назначения;
доступность больших объёмов виртуальной памяти;
развитый сервис операционной системы, обилие функций, облегчающих разработку приложений;
многообразие и доступность средств создания интерфейса с пользователем (диалоги, меню и т.п.).
Современный ассемблер, к которому относится и TASM 5.0 фирмы Borland International Inc., в свою очередь, развивал средства, которые ранее были характерны только для языков высокого уровня. К таким средствам можно отнести макроопределение вызова процедур, возможность введения шаблонов процедур (описание прототипов) и даже объектно-ориентированные расширения.
Все эти факторы позволяют рассматривать ассемблер, как самостоятельный инструмент для написания приложений на платформе Win32 (Windows NT и Windows 98).
2.2 Вызов функций Win32 api в программах на языке ассемблер
Функции Win32 API находятся в системных DLL-библиотеках. Поэтому их вызов осуществляется с учетом некоторых правил:
все используемые функции Win32 API должны быть объявлены как внешние с помощью директивы extrn;
программа должна компоноваться с библиотекой импорта import32.lib, в которой находится информация о местонахождении функций Win32 API;
параметры функциям передаются через стек в обратном порядке; очистка стека от параметров осуществляет сама функция.
Например, функцию Win32 API
int MessageBox(
HWND hWnd, //дескриптор окна владельца
LPCTSTR lpText, //адрес строки сообщения
LPCTSTR lpCaption,//адрес строки заголовка сообщения
UINT uType //стиль окна
);
можно использовать в программе на ассемблере следующим образом:
;указание tlink32, что программа должна компоноваться с
;библиотекой импорта import32.lib
includelib import32.lib
;объявление внешней функции MessageBoxA
extrn MessageBoxA :proc
MB_OK = 0
.data
szMessage db 'Это сообщение.', 0
szTitle db 'Заголовок сообщения', 0
...
.code
...
push MB_OK
push offset szTitle
push offset szMessage
push 0
call MessageBoxA
...
Кроме этого функции Win32 API можно объявлять более удобным способом с помощью директивы procdesc. Использование этой директивы (а так же ее преимущества) можно увидеть на следующем примере
includelib import32.lib
;объявление внешней функции MessageBoxA
MessageBoxA procdesc :dword, :dword, :dword, :dword
MB_OK = 0
.data
szMessage db 'Это сообщение.', 0
szTitle db 'Заголовок сообщения', 0
...
.code
...
call MessageBoxA, 0, offset szMessage,\
offset szTitle, MB_OK
...
Как видно из примера, функция объявляется с указанием количества и типов параметров (обычно все параметры функций 32-разрядные), а вызов ее осуществляется в стиле языка С.