Шаг 112 - Вызовы функций и типы вызовов

Давайте для начала определимся как все-таки функции вызывается. На ассемблере создается процедура примерно так, а вообще она может в разных реализациях организовываться по разному.

PROC TEST
......
RET
END PROC

RET - это команда возврата из функции. Сама функция вызывается командой CALL. Вот так например.

CALL TEST

Идея понятна. Ни на грамм не сложнее чем в C++. Только вот при вызове функции нужно передавать параметры. Вообще не так много способов передать параметры

Но это еще не все. Когда параметров много, передать их можно с права налево или наоборот. Итак, первая проблема разнообразия способов вызова заключается в том, как передаются параметры. Через что и в каком направлении. Но и это еще не все. Если параметры допустим с стеке, то есть два варианта кто будет их оттуда убирать. Для работы со стеком в ассемблере есть две команды pop и push. С помощью них что-то помещается и извлекается из стека. При вызове функции ее адрес помещается в стек. При вызове Ret и возврата этот адрес из стека извлекается. Итак, при вызове параметры помещаются в стек, после вызова они должны из стека очиститься, так кто это делает кто вызывал или кого вызывают ? Вот все эти причины и порождают разнообразие методов вызова функций. Но и это еще не все. Еще один вопрос как будут интерпретироваться имена. Обычно когда Вы пишите функции на C++ вы об этом не задумываетесь, так как все вызовы идут по одному правилу. Это правило устанавливается в Project settings.

112_1.gif (9559 b)

По умолчанию используется _cdecl - это стандартные правила вызовов C++. Windows, например, использует _stdcall. Поэтому к функциям Windows нам нужно обращаться используя stdcall. Что делать ? Перед функцией можно поставить модификатор, который будет указывать как функция вызывается, то есть по каким правилам. Вот так это делается:

void __stdcall Test();
void __cdecl Test1();

А вообще эти вызовы окутывают в определения, например WINAPI не что иное как:

#define WINAPI      __stdcall
#define CALLBACK    __stdcall

Что ясности не добавляет, но деваться некуда. Если правила вызовов будут изменены, то нужно будет просто перекомпилировать программу, в теории так, на практике все равно придется устранять всякие там баги.


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 02.09.2001