调用约定
 
指定如何调用过程。

调用约定确定调用代码如何在调用时与过程进行交互。它们指定了参数如何推送到调用堆栈的规则,值如何返回以及调用堆栈被清理时。当与其他语言编写的代码(特别是汇编语言)进行交互时,此信息非常有用。在某些情况下,调用约定也会对过程名称应用某种名称装饰。

FreeBASIC支持3种调用规则:STDCALLCDECLPascal,分别由stdcallcdeclpascal指定。可以在过程名称后面的过程声明或定义中指定调用约定。过程的声明必须与定义具有相同的调用约定。

在所有调用约定中,积分过程返回值在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.

参考