visual c中使用的fastcall关键字是什么?

Rau*_*ulp 8 calling-convention visual-c++ fastcall

fastcall在许多函数之前看过附加的符号.为什么用它?

Mah*_*dsi 23

该函数之前的符号称为"调用约定".它指定编译器如何(在较低级别)将输入参数传递给函数并在执行后检索其结果.

有许多不同的呼叫约定,最受欢迎的是stdcallcdecl.

您可能认为只有一种方法可以实现,但实际上,有许多方法可以调用函数并将变量传入和传出.您可以将输入参数放在堆栈上(push,push,push to call; pop,pop,pop来读取输入参数).或者你可能宁愿把它们放在寄存器中(这是fastcall- 它试图在寄存器中加入一些输入参数以获得速度).

但那顺序怎么样?你是从左到右还是从右到左推动它们?结果如何 - 总是只有一个(假设没有参考参数),那么你将结果放在堆栈中,寄存器中,某个存储器地址吗?

另外,让我们假设你正在使用堆栈进行通信 - 在调用函数之后实际清除堆栈的工作是谁 - 调用者还是被调用者?

那么备份然后恢复(某些)CPU寄存器的内容怎么样 - 如果调用者这样做,或者被调用者是否保证它将按照它的方式返回所有内容?

最流行的调用约定(到目前为止)是cdeclC和C++中的标准调用约定.WIN32 API使用stdcall,这意味着调用WIN32 API的任何代码都需要stdcall用于那些函数调用(使其成为另一种流行的选择).

fastcall有点奇怪 - 人们只用一个输入/输出参数实现了许多功能,从基于内存的堆栈中推送和弹出是相当多的开销,并使函数调用有点沉重,因此引入了不同的编译器(不同)调用约定,在将其余参数放入堆栈之前将一个或多个参数放入寄存器中以获得更好的性能.问题是,并非所有编译器都使用相同的规则来处理使用它的地方和使用者fastcall,因此在使用它时必须小心,因为你永远不会知道是谁做了什么.最后,看看fastcall真的更快吗?有关fastcall性能优势的信息.

复杂的东西.

需要记住的重要事项:如果您不确切知道自己在做什么,请不要添加或更改调用约定,因为如果调用者和被调用者都不同意调用约定,您可能最终会堆栈损坏和段错误.这通常发生在DLL /共享库中调用函数并且编写的程序依赖于DLL/SO/dylib是某种调用约定(例如cdecl),然后使用不同的调用约定重新编译库(比方说fastcall).现在,旧程序无法再与新库通信.