Соглашение о вызове


Соглашение о вызове (англ. calling convention) — описание технических особенностей вызова подпрограмм, определяющее:

Соглашение о вызове может быть описано в документации к ABI архитектуры, в документации к ОС или в документации к компилятору.

Для перечисленных ниже соглашений (кроме cdecl) перед возвратом значений из функции подпрограмма обязана восстановить значения сегментных регистров, регистров esp и ebp. Сохранением-восстановлением остальных регистров занимается вызывающая программа.

Если размер возвращаемого значения функции не больше размера регистра eax, возвращаемое значение сохраняется в регистре eax. Иначе возвращаемое значение сохраняется на вершине стека, а указатель на вершину стека сохраняется в регистре eax. Если возвращается объект с автодеструктором (любой объект C++ с ненулевым деструктором, строки произвольной длины в Паскале, BSTR в WinAPI и т. д.), вызывающая программа должна корректно уничтожить его.

cdecl (сокращение от англ. c-declaration) — соглашение о вызовах, используемое компиляторами для языка Си (отсюда название).

Аргументы функций передаются через стек, справа налево. Аргументы, размер которых меньше 4 байт, расширяются до 4 байт. За сохранение регистров EAX, ECX, EDX и стека сопроцессора отвечает вызывающая программа, за остальные — вызываемая функция. Очистку стека производит вызывающая программа. Это основной способ вызова функций с переменным числом аргументов (например, printf()). Способы получения возвращаемого значения функции приведены в таблице.