На этом шаге мы рассмотрим общие правила вызова функций 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.