闲话__stdcall, __cdecl, __fastcall出现的历史背景以及各自解决的问题

可以认为最先由微软搞出来了__stdcall, 其实就是和WINAPI的声明是一样的,入栈顺序是从右到左,函数返回时,会进行出栈操作。

PASCAL语言是非常古老的编程语言,在C语言之前,因此在当时的时代中,PASCAL的调用约定也是__stdcall

后来在C语言中发现__stdcall不支持变长参数的函数调用,比如printf,可以携带任意N个参数。我们查看WINDOWS的API,是找不到类似这样的函数声明的。 因此在C语言中,就使用了另外一种调用约定:__cdecl ,为了解决任意参数的问题,它把出栈的工作交给了调用者,而不是在函数内部进行出栈,因为调用者是知道传递了多少个参数的。比如printf,调用printf的代码知道究竟传递了多少个参数进去,那么在函数返回后,它自然就知道要出栈多少个参数了。

__cdecl因为由调用者清理栈,在函数被频繁调用时,整个程序中会生成大量的出栈代码,因此最终程序体积会稍大。

在说__fastcall之前,我们先聊聊目前移动设备中的处理器:ARM芯片,ARM中的函数调用都是通过寄存器传递的,并没有通过入栈和出栈来传递参数。 WHY?答案就是性能。因此历史上的BORLAND公司的C++BUILDER提供了__fastcall的调用约定,参数都是通过寄存器来进行传递,只有寄存器不够时,才使用栈来操作。而微软对于__fastcall的支持并不是很广泛。可见当时C++BUILDER及VCL组件技术上确实非常牛逼,秒杀微软VC中的MFC。

__fastcall的返回方式类似于__stdcall,函数返回时进行出栈操作(如果有用到栈的话),因此它也不支持可变参数。


参考:http://blog.csdn.net/zjwoody/article/details/7887988

原文地址:https://www.cnblogs.com/swnuwangyun/p/7837449.html