Соглашения о вызове подпрограмм, используемые в Delphi
При объявлении процедуры или функции можно указать соглашение о вызове при помощи одной из директив register, pascal, cdecl, stdcall, и safecall. Например,
function MyFunction(X, Y: Real): Real; cdecl;
...
Соглашения о вызове определяют порядок передачи параметров в программу. Они также влияют на удаление параметров из стека, использование регистров для передачи параметров, а также на обработку ошибок и исключений. По умолчанию используется соглашение о вызове register.
-
Соглашения register и pascal передают параметры слева направо; это означает, что самый левый парметр оценивается и передается первым, а самый правый - последним. Соглашения cdecl, stdcall и safecall передают параметры справа нелево.
В следующаей таблице приведены краткие сведения о соглашениях о вызове:
Директива |
Порядок параметров |
Место очистки стека |
register |
Слева напрво |
Подпрограмма |
pascal |
Слева направо |
Подпрограмма |
cdecl |
Справа налево |
Вызываюшая программа |
stdcall |
Справа налево |
Подпрограмма |
safecall |
Справа налево |
Подпрограмма |
Соглашение по умолчанию, register, является наиболее эффективным, поскольку при его использовании можно избежать создания фрейма стека. При этом первые три параметра передаются в регистрах (первый - в EAX, второй - в EDX, третий - в ECX), а остальные, если они есть, передаются в стеке.
Соглашение cdecl используется при вызове функций из DLL, написанных на языках C и C++. Соглашения stdcall и safecall следует использовать для вызова функций Windows API. Соглашение pascal поддерживается для обратной совместимости со старыми программами.
Директивы near, far и export используются в соглашениях о вызове для 16-разрядных приложений Windows. Они не играют никакой роли в 32-х разрядных приложениях, и существуют только для совместимости со старым кодом.