可以认为最先由微软搞出来了__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

闲话__stdcall, __cdecl, __fastcall出现的历史背景以及各自解决的问题的更多相关文章

  1. __stdcall,__cdecl,__fastcall的区别

    __stdcall,__cdecl,__fastcall的区别 标签: dll编译器pascalclassimportinitialization 2009-12-09 15:07 10472人阅读  ...

  2. 【C/C++开发】__stdcall,__cdecl,__fastcall的区别

    __stdcall和__cdecl的区别 __stdcall和__cdecl是两种函数名字修饰.(注意是连续的两个下划线) Windows上 windows上不管是C还是C++,默认使用的都是__st ...

  3. __stdcall,__cdecl,__fastcall,_stdcall,_cdecl,_fastcall 区别简介[转]

    今天写线程函数时,发现msdn中对ThreadProc的定义有要求: DWORD WINAPI ThreadProc(LPVOID lpParameter);   不解为什么要用WINAPI宏定义,查 ...

  4. (转)__cdecl __fastcall与 __stdcall

    原帖 http://blog.sina.com.cn/s/blog_6b7c56870100l8rf.html __cdecl   __fastcall与   __stdcall 调用约定:  __c ...

  5. 调用约定__cdecl __fastcall与__stdcall

    __cdecl __fastcall与__stdcall,三者都是调用约定(Calling convention),它决定以下内容:1)函数参数的压栈顺序,2)由调用者还是被调用者把参数弹出栈,3)以 ...

  6. C调用约定__cdecl、__stdcall、__fastcall、__pascal分析

    参考原文地址:https://www.cnblogs.com/yenyuloong/p/9626658.html C/C++ 中不同的函数调用规则会生成不同的机器代码,产生不同的微观效果,接下来让我们 ...

  7. __cdecl、__stdcall、__fastcall 与 __pascal 浅析

    call 指令与 retn 指令 首先我们得了解 CALL 和 RETN 指令的作用,才能更好地理解调用规则,这也是先决条件. 实际上,CALL 指令就是先将下一条指令的 EIP 压栈,然后 JMP ...

  8. 论山寨手机与Android联姻 【1】MTK亮相的历史背景

    [1]MTK亮相的历史背景如果说1960年代是大型机(Mainframe)的时代,1970年代是小型机(Microcomputer)的时代,那么1980年代无疑是个人电脑(PC)的时代,而1990年代 ...

  9. __stdcall __cdecl 引起的程序崩溃

    崩溃弹出的截图如下 看到0xC0000005, 访问冲突的问题, 九成九是内存访问违规, 比如访问了已经释放的指针, 又或者是离开函数时栈被破坏之类. 找了一下午一直没有头绪, 好在有一份可以执行的源 ...

随机推荐

  1. 设备驱动与控制器 I/O

    控制器是对硬件发起控制命令,负责给系统提供接口,想要正常使用该硬件功能系统中必须安装相应驱动 I/O设备 cpu和存储器并不是操作系统唯一需要管理的资源,I/O设备也是非常重要的一环. I/O设备一般 ...

  2. 使用cygwin移植Linux的项目到Windows下之总结(转)

    使用cygwin移植Linux的项目到Windows下之总结(转) 原文 http://my.oschina.net/michaelyuanyuan/blog/68615?p=1   一.why   ...

  3. maven工具使用之常用maven命令(二)

    1.创建java web项目: # mvn archetype:generate -DgroupId=com.igoodful.sdxs      -DartifactId=hubu  -Darche ...

  4. 什么是Http无状态?Session、Cookie、Token三者之间的区别

    一.什么是HTTP无状态? 1.1定义: HTTP无状态协议,是指协议对于交互性场景没有记忆能力. 1.2举个例子: 在点击一个纯的html网页,请求获取服务器的html文件资源时,每次http请求都 ...

  5. 用random模块实现验证码

    #! /usr/bin/env python3 import random checkcode = "" ## 全部为数字的验证码 # for i in range(4): # c ...

  6. [转]HTML标签元素的分类

      在讲解CSS布局之前,我们需要提前知道一些知识,在CSS中,html中的标签元素大体被分为三种不同的类型:块状元素.内联元素和内联块状元素. 常用的块状元素有: <div>.<p ...

  7. 20145240《网络对抗》Web基础

    Web基础 实验后回答问题 什么是表单? 表单在网页中主要负责数据采集功能. 一个表单有三个基本组成部分: 表单标签:这里面包含了处理表单数据所用CGI程序的URL以及数据提交到服务器的方法. 表单域 ...

  8. 起源游戏临时实体(Temp Entity)

    如何查看实体 https://wiki.alliedmods.net/Temp_Entity_Lists_(Source) 这里是部分游戏的临时实体列表 # 还可以通过在游戏内输入来获取游戏的临时实体 ...

  9. Redis-与python交互

    安装包 到中文官网查找客户端代码 联网安装 sudo pip install redis 使用源码安装 unzip redis-py-master.zip cd redis-py-master sud ...

  10. SaltStack应用grains和jinja模板-第四篇

    目标需求 1.使用jinja模板让apache配置监听本地ip地址 2.了解grains的基本使用方法 说明:实验环境是在前面的第二篇和第三篇基础上完成 实现步骤 使用grains获取ip地址信息 使 ...