Win32ASM Минимальное приложение

  d8ef8794     

вызов функций API из программы


Как я уже говорил в п.7, вызов функций API из программы на ассемблере подчиняется соглашению "stdcall". Выражаясь официозно, "с точки зрения прикладного программиста, с учетом специфики Windows и MASM", эти соглашения заключаются в следующем:
1. Регистр символов в имени функции не имеет значения. Например, функции с именами WindowsMustDie и windowsmustdie - это одна и та же функция. Здесь мы наблюдаем отличие от требования языков C и C++, в которых идентификаторы регистро-зависимы. Зато в Паскале регистр имен не имеет значения.
  2. Аргументы передаются вызываемой функции через стек. Если аргумент укладывается в 32-битное значение и не подлежит модификации вызываемой функцией, он обычно записывается в стек непосредственно. В остальных случаях программист должен разместить значение аргумента в памяти, а в стек записать 32-битный указатель на него. Таким образом, все параметры, передаваемые функции API, представляются 32-битными величинами.
  3. Вызывающая программа загружает аргументы в стек последовательно, начиная с последнего, указанного в описании функции, и кончая первым. После загрузки всех аргументов программа вызывает функцию командой call.
  4. За возвращение стека в исходное состояние после возврата из функции API отвечает сама вызываемая функция. Программисту заботиться о восстановлении указателя стека esp нет необходимости. Эта идея тоже пришла из реализаций Паскаля и прилично экономит на размере кода.
  5. Вызываемая функция API гарантированно сохраняет регистры общего назначения ebp, esi, edi. Регистр eax, как правило, содержит возвращаемое значение. Состояние остальных регистров после возврата из функции API следует считать неопределенным (полный набор соглашений stdcall регламентирует также сохранение системных регистров ds и ss. Однако для flat-модели памяти, используемой в win32, эти регистры значения не имеют.)
  В применении к нашему примеру это означает следующее:
  - аргументы мы должны передать через стек;
  - сама фунция вызывается командой call;
  - не "парим" себе мозги, задаваясь вопросом, "если мы сделали PUSH, то когда же нам сделать POP?", ибо правильный ответ - никогда. Об этом позаботиться сама функция.

 

Содержание раздела