Конвенции вызовов
 
Спецификации о том, как вызываются функции.

Соглашения о вызовах определяют, как вызывающий код взаимодействует с процедурами при вызове. Они определяют правила о том, как параметры помещаются в стек, как возвращаются значения и когда очищается стек. Эта информация полезна при взаимодействии с кодом, написанным на других языках, особенно для языка ассемблера. В некоторых случаях соглашения о вызовах также применяются как оформление имен процедур.

FreeBASIC поддерживает 3 конвенции: stdcall, cdecl и pascal, определяемые с stdcall, cdecl и pascal, соответственно. Вызываемая конвенция может быть определена в декларации процедуры или в определении сразу после названия процедуры. У декларации процедуры должно быть то же самое соглашение конвенции как и в определении.

Во всех вызовах, интегральные процедуры возвращают значения в регистры EAX(, EDX) , а значения с плавающей точкой сохраняются в регистре ST(0) (в верхней части стека). Значения пользовательского типа (UDT) возвращаются в регистры EAX(, EDX) , если значение размером восемь(8) байт или меньше, в противном случае они возвращаются в памяти, адрес которой лежит в стеке после каких-либо параметров.

stdcall

В конвенции stdcall параметры процедур помещаются в стек до вызова процедуры в обратном порядке, а не в том, котором они объявлены, то есть справа налево. Адрес возврата заталкивается чуть выше параметров. Процедура отвечает за выталкивание всех параметров из стека (обычно путем добавления константы к инструкции RET, означающее количество байт для освобождения).

stdcall по умолчанию конвенция вызовов на Windows, и для процедур с блоками Extern "Windows" и Extern "Windows-Ms" . Это конвенция по умолчанию так же используется в Windows API.

Platform Differences

  • На DOS и Windows платформах, имя процедуры оформляется с суффиксом "@N", где N общий размер в байтах всех параметров.

cdecl

В конвенции cdecl, параметры процедур помещаются в стек до вызова процедуры в обратном порядке, а не в том, котором они объявлены, то есть справа налево. Вызывающий код отвечает за выталкивание параметров из стека.

cdecl по умолчанию конвенция вызовов для Linux, *BSD, и DOS, и для процедур с блоками Extern "C" и Extern "C++". Так же эта конвенция по умолчанию для компиляторов C и C++.

pascal

В конвенции pascal параметры процедуры помещаются в стек, в порядке их объявления, то есть слева направо. Процедура отвечает за выталкивание всех параметров из стека.

pascal является конвенцией по умолчанию для Pascal и серии компиляторов Microsoft QuickBASIC.

В следующей таблице приведены различия между конвенциями:

Конвенция вызовов Параметры помещаются в стеке вызова Параметры выталкиваются из стека 
stdcall справа налево процедурой
cdecl справа налево вызывающим кодом
pascal слева направо процедурой


Различия платформ

  • На DOS и Windows платформах все соглашения о вызове оформлены в виде префиксов ("_") к именам процедур.
  • По умолчанию конвенция вызовов меняется в зависимости от платформы. Для Windows это stdcall; Для Linux, *BSD, и DOS это cdecl.

См. также