指定如何调用过程。
调用约定确定调用代码如何在调用时与过程进行交互。它们指定了参数如何推送到调用堆栈的规则,值如何返回以及调用堆栈被清理时。当与其他语言编写的代码(特别是汇编语言)进行交互时,此信息非常有用。在某些情况下,调用约定也会对过程名称应用某种名称装饰。
FreeBASIC支持3种调用规则:
STDCALL,
CDECL和
Pascal,分别由
stdcall,
cdecl和
pascal指定。可以在过程名称后面的过程声明或定义中指定调用约定。过程的声明必须与定义具有相同的调用约定。
在所有调用约定中,积分过程返回值在
EAX(,
EDX)寄存器中返回,浮点返回值存储在
ST(0)寄存器(浮点堆栈的顶部) )。如果八(
8)个字节或更小,则
EAX(,
EDX)寄存器中返回用户定义类型(UDT)值,否则通过将其地址推送到调用堆栈后任何参数。
STDCALL
在
STDCALL约定中,程序参数在过程调用之前被推送到调用堆栈上(这将按照它们被声明的相反顺序,即从右到左)按照与之相反的顺序将返回地址推送到参数上方。该过程负责从调用堆栈中弹出任何参数(通常通过将常量附加到
RET指令,表示要释放的字节数)。
STDCALL是Windows上的默认调用约定,以及
Extern "Windows"和
Extern "Windows-Ms"块中的过程。它也是Windows API中使用的默认约定。
平台差异
- 在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.
参考