Соглашение о вызове (англ. calling convention) — описание технических особенностей вызова подпрограмм, определяющее:
Соглашение о вызове может быть описано в документации к ABI архитектуры, в документации к ОС или в документации к компилятору.
Для перечисленных ниже соглашений (кроме cdecl
) перед возвратом значений из функции подпрограмма обязана восстановить значения сегментных регистров, регистров esp
и ebp
. Сохранением-восстановлением остальных регистров занимается вызывающая программа.
Если размер возвращаемого значения функции не больше размера регистра eax
, возвращаемое значение сохраняется в регистре eax
. Иначе возвращаемое значение сохраняется на вершине стека, а указатель на вершину стека сохраняется в регистре eax
. Если возвращается объект с автодеструктором (любой объект C++ с ненулевым деструктором, строки произвольной длины в Паскале, BSTR в WinAPI и т. д.), вызывающая программа должна корректно уничтожить его.
cdecl
(сокращение от англ. c-declaration) — соглашение о вызовах, используемое компиляторами для языка Си (отсюда название).
Аргументы функций передаются через стек, справа налево. Аргументы, размер которых меньше 4 байт, расширяются до 4 байт. За сохранение регистров EAX, ECX, EDX и стека сопроцессора отвечает вызывающая программа, за остальные — вызываемая функция. Очистку стека производит вызывающая программа. Это основной способ вызова функций с переменным числом аргументов (например, printf()
). Способы получения возвращаемого значения функции приведены в таблице.