На этом шаге мы рассмотрим общие правила вызова функций API.
Начнем с того, как можно вызвать функции API. Обратимся к файлу помощи и выберем любую функцию API, например, MessageBox:
int MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT Type);
Данная функция выводит на экран окно с сообщением и кнопкой (или кнопками) выхода. Смысл параметров:
Теперь о типах параметров. Все они в действительности 32-битные целые числа:
CALL MessageBoxA@16.
А как же быть с параметрами? Их следует предварительно поместить в стек командами PUSH. Запомните правило: слева направо - снизу вверх. Итак, пусть дескриптор окна расположен по адресу HW, строки - по адресам STR1 и STR2, а тип окна-сообщения - это константа. Самый простой тип имеет значение 0 и называется MB_OK. Имеем следующее:
МВ_ОК equ 0
. . . .
STR1 DB "Неверный ввод! ", 0
STR2 DB "Сообщение об ошибке.",0
HW DWORD ?
. . . .
PUSH МВ_ОК
PUSH OFFSET STR1
PUSH OFFSET STR2
PUSH HW
CALL MessageBoxA@16
Как видите, все весьма просто и ничуть не сложнее, как если бы вы вызывали эту функцию на C или Delphi. Результат выполнения любой функции - это, как правило, целое число, которое возвращается в регистре ЕАХ.
Аналогичным образом в Ассемблере легко воспроизвести те или иные C-структуры.
Рассмотрим, например, структуру, определяющую системное сообщение:
typedef struct tagMSG { // msg
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt; } MSG;
Это сообщение будет далее подробно прокомментировано в одном из примеров. На ассемблере эта структура будет иметь вид:
MSGSTRUCT STRUC
MSHWND DD ?
MSMESSAGE DD ?
MSWPARAM DD ?
MSLPARAM DD ?
MSTIME DD ?
MSPT DD ?
MSGSTRUCT ENDS
Как видите, на ассемблере все даже гораздо проще.
На следующем шаге мы более подробно остановимся на структуре программы для Windows.