Соглашение о вызове (англ. calling convention) — описание технических особенностей вызова подпрограмм, определяющее:
Является частью двоичного интерфейса приложений (англ. application binary interface, ABI).
Соглашение о вызове описывает следующее:
printf()
) (так как на вершине стека оказывается всегда первый аргумент);call
и ret
; при работе в стандартном режиме используются инструкции call near
, call far
и pushf/call far
(для возврата соответственно retn
, retf
и iret
);this
или self
) в объектно-ориентированных языках. Варианты (для процессора x86, работающего в защищённом режиме):
ecx
или rcx
;Соглашение о вызове может быть описано в документации к ABI архитектуры, в документации к ОС или в документации к компилятору.
Для перечисленных ниже соглашений (кроме cdecl
) перед возвратом значений из функции подпрограмма обязана восстановить значения сегментных регистров, регистров esp
и ebp
. Значения остальных регистров могут не восстанавливаться.
Если размер возвращаемого значения функции не больше размера регистра eax
, возвращаемое значение сохраняется в регистре eax
. Иначе, возвращаемое значение сохраняется на вершине стека, а указатель на вершину стека сохраняется в регистре eax
.
cdecl
(сокращение от англ. c-declaration) — соглашение о вызовах, используемое компиляторами для языка Си (отсюда название).
Аргументы функций передаются через стек, справа налево. Аргументы, размер которых меньше 4-х байт, расширяются до 4-х байт. Очистку стека производит вызывающая программа. Это основной способ вызова функций с переменным числом аргументов (например, printf()
). Способы получения возвращаемого значения функции приведены в таблице.
Тип | Размер возвращаемого значения, байт | Способ передачи возвращаемого значения | Примечание |
---|---|---|---|
Целое число, указатель | 1, 2, 4 | Через регистр eax |
Значения, размер которых меньше 4-х байт, расширяются до 4-х байт |
Целое число | 8 | Через пару регистров edx:eax |
|
Число с плавающей точкой | 4, 8 | Через регистр st0 (из псевдостека x87, FPU) |
|
Другие | Больше 8 | Через регистр eax |
Указатель на структуру данных сохраняется в регистре eax |
Перед вызовом функции вставляется код, называемый прологом (англ. prolog) и выполняющий следующие действия:
После вызова функции вставляется код, называемый эпилогом (англ. epilog) и выполняющий следующие действия:
pascal
— соглашение о вызовах, используемое компиляторами для языка Паскаль. Также применялось в ОС Windows 3.x.
Аргументы процедур и функций передаются через стек, слева направо. Указатель на вершину стека (значение регистра esp
) на исходную позицию возвращает подпрограмма. Изменяемые параметры передаются только по ссылке. Возвращаемое значение передаётся через изменяемый параметр Result. Параметр Result создаётся неявно и является первым аргументом функции.
stdcall
или winapi
— соглашение о вызовах, применяемое в ОС Windows для вызова функций WinAPI.
Аргументы функций передаются через стек, справа налево. Очистку стека производит вызываемая подпрограмма.
fastcall
— общее название соглашений, передающих параметры через регистры (обычно это самый быстрый способ, отсюда название). Если для сохранения всех параметров и промежуточных результатов регистров не достаточно, используется стек.
Соглашение о вызовах fastcall
не стандартизировано, поэтому используется только для вызова процедур и функций, не экспортируемых из исполняемого модуля и не импортируемых извне.
В компиляторах фирмы Borland для соглашения __fastcall
, называемого также register
[5], параметры передаются слева направо в регистрах eax
, edx
, ecx
, а если параметров больше трёх — в стеке, также слева направо. Исходное значение указателя на вершину стека (значение регистра esp
) возвращает вызываемая подпрограмма.
В 32-разрядной версии компилятора фирмы Microsoft[6], а также в компиляторе GCC[7], соглашение __fastcall
, также называемое __msfastcall
, определяет передачу первых двух параметров слева направо в регистрах ecx
и edx
, а остальные параметры передаются справа налево в стеке. Очистку стека производит вызываемая подпрограмма.
safecall
— соглашение о вызовах, используемое для вызова методов интерфейсов COM.
Методы интерфейсов COM представляют собой функции, возвращающие тип HRESULT. Код, добавляемый после вызова функции, анализирует возвращаемое значение. При наличии ошибки код записывает код ошибки, сообщение о ошибке и поднимает исключение. Иначе настоящее возвращаемое значение скрывается, вместо него используется параметр, передаваемый в функцию последним по ссылке. Например, можно считать два следующих объявления функции эквивалентными.
// safecall
function DoSomething ( a : DWORD ) : DWORD ; safecall ;
// симуляция safecall
function DoSomething ( a : DWORD ; out Result : DWORD ) : HResult ; stdcall ;
thiscall
— соглашение о вызовах, используемое компиляторами для языка C++ при вызове методов классов в объектно-ориентированном программировании.
Аргументы функции передаются через стек, справа налево. Очистку стека производит вызывающая программа. Соглашение thiscall
отличается от cdecl
соглашения только тем, что указатель на объект, для которого вызывается метод (указатель this
), записывается в регистр ecx
[8].
В этой статье не хватает ссылок на источники информации. |
Данная страница на сайте WikiSort.ru содержит текст со страницы сайта "Википедия".
Если Вы хотите её отредактировать, то можете сделать это на странице редактирования в Википедии.
Если сделанные Вами правки не будут кем-нибудь удалены, то через несколько дней они появятся на сайте WikiSort.ru .