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