__cdecl __fastcall与__stdcall,三者都是调用约定(Calling convention),它决定以下内容:1)函数参数的压栈顺序,2)由调用者还是被调用者把参数弹出栈,3)以及产生函数修饰名的方法。
1、__stdcall调用约定:函数的参数自右向左通过栈传递,被调用的函数在返回前清理传送参数的内存栈。
2、__cdecl是C和C++程序的缺省调用方式。每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。函数采用从右到左的压栈方式。注意:对于可变参数的成员函数,始终使用__cdecl的转换方式。
3、__fastcall调用约定:它是通过寄存器来传送参数的(实际上,它用ECX和EDX传送前两个双字(DWORD)或更小的参数,剩下的参数仍旧自右向左压栈传送,被调用的函数在返回前清理传送参数的内存栈)。
4、thiscall仅仅应用于"C++"成员函数。this指针存放于CX寄存器,参数从右到左压。thiscall不是关键词,因此不能被程序员指定。
5、nakedcall采用1-4的调用约定时,如果必要的话,进入函数时编译器会产生代码来保存ESI,EDI,EBX,EBP寄存器,退出函数时则产生代码恢复这些寄存器的内容。naked call不产生这样的代码。naked call不是类型修饰符,故必须和_declspec共同使用。

以前看windows编程时一直有个 _stdcall 函数调用约定 一直不是很理解,只能硬记。 现在终于在《程序是怎样跑起来的》这本书书中找到了答案。

1. _stdcall 是standard call (标准调用) 的略称

Windows提供的DLL文件内的函数基本上都是_stdcall调用方式。但用C语言编写的程序内的函数,默认设置都不是 _stdcall. C语言特有的调用方式成为C调用,之所以默认不使用 _stdcall, 是因为C语言所对应的函数传入的参数是可变的,只有函数调用方才能知道到底有多少个参数,这种情况下,栈的清理作业便无法进行(关于这点会在下面详细说明)。不过,如果在C语言中函数的参数固定的话,指定 _stdcall 是没有问题的。

2. 通过 _stdcall 调用来减小程序文件的大小

   C语言中,在调用函数后,需要执行栈清理处理指令。指的是把不需要的数据从接收和传递函数的参数时使用的内存上的栈区域清理出去。该命令是在程序编译时由编译器自动附加到程序中的,编译器默认将该处理附在函数调用方。在同一个程序中,同样的函数可能会被反复调用多次,而如果是同样的函数,栈清理处理的内容也是一样。由于该处理是在调用函数一方,因此就会导致同一处理被反复进行,造成内存浪费。、

栈清理处理,比起在函数调用方进行,在反复被调用的函数一方进行时,程序整体要小一些。这时所使用的就是 _stdcall。在函数前加上 _stdcall 就可以把栈清理处理变为在被调用函数一方进行。下面是图示:

_stdcall的更多相关文章

  1. _stdcall,_cdecl区别

    (1) _stdcall调用 _stdcall是Pascal程序的缺省调用方式,参数采用从右到左的压栈方式,被调函数自身在返回前清空堆栈. WIN32 Api都采用_stdcall调用方式,这样的宏定 ...

  2. _stdcall与_cdecl(了解)

    调用约定(Calling Convention)是指在程序设计语言中为了实现函数调用而建立的一种协议.这种协议规定了该语言的函数中的参数传送方式.参数是否可变和由谁来处理堆栈等问题.不同的语言定义了不 ...

  3. __stdcall,__cdecl,_cdecl,_stdcall,。__fastcall,_fastcall 区别简介

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

  4. 教你看懂C++类库函数定义之三---_stdcall

    一切从一个C++ 类库头文件开始,现在在做一个C++的项目,期间用到一个开源的界面库DUILib(类似MFC),这个东西还不错能很容易的写出漂亮的界面,比如QQ的界面,可以去下载下来研究研究,地址:h ...

  5. VC生成lib的_stdcall函数名与mingw生成的不一致

    Qt Creator在Windows系统中,怎样链接VC生成的动态链接库 这个问题曾经困扰了我一整天.我想的是按照VC中的方法,增加include文件,增加lib文件,然后编译即可.谁知链接时总是出现 ...

  6. 函数调用的区别:_cdecl以及_stdcall

    一.概念1)_stdcall调用   _stdcall是Pascal程序的缺省调用方式,参数采用从右到左的压栈方式,由调用者完成压栈操作,被调函数自身在返回前清空堆栈.   WIN32 Api都采用_ ...

  7. C++编译器详解(三)函数调用的区别:_cdecl以及_stdcall

    1._stdcall是Pascal程序的缺省调用方式,通常用于Win32 API中,函数采用从右到左的压栈方式,自己在退出时清空堆栈.VC将函数编译后会在函数名前面加上下划线前缀,在函数名后加上&qu ...

  8. _stdcall 和 _cdecl

    今天遇到一个问题用C++编写一个动态链接库生成的文件为dll.dll,用在visual stdio 2010调用这个dll 调用形式:[DllImport("dll.dll")] ...

  9. 函数调用方法之__cdecl与_stdcall

    在debug VS c工程文件时,碰到cannot convert from 'int (__cdecl *)(char *)' to 'xxx'这个问题,发现问题在于typedef函数指针类型时,将 ...

  10. _stdcall调用

    以前看windows编程时一直有个 _stdcall 函数调用约定 一直不是很理解,只能硬记. 现在终于在<程序是怎样跑起来的>这本书书中找到了答案. 1. _stdcall 是stand ...

随机推荐

  1. yii2框架的安装&配置启动

    top:环境MacBook 1.通过composer 安装yii2 [yii2需要php的PDO和pdo_mysql扩展,需要确认已安装] a. 首先需要配置composer:我使用的是阿里云的镜像: ...

  2. Java多线程引例及实现多线程的方式

    多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术. Java多线程是由JVM来实现,不必关心操作系统的调用问题. 假如我们要实现如下功能: public c ...

  3. 史上最全USB HID开发资料

    史上最全USB HID开发资料 史上最全USB HID开发资料,悉心整理一个月,亲自测试. 涉及STM32 C51 8051F例子都有源码,VC上位机例子以及源码,USB协议,HID协议,USB抓包工 ...

  4. Spring框架各Jar包说明

    来源:https://blog.csdn.net/weisong530624687/article/details/50888094 前言: (1)spring.jar 是包含有完整发布模块的单个ja ...

  5. Vagrant 手册之 Vagrantfile - 最低版本

    原文地址 可以在 Vagrantfile 中指定一组 Vagrant 的版本,以强制人们使用带有 Vagrantfile 的特定版本的 Vagrant.这可以帮助解决使用带有 Vagrantfile ...

  6. Mac获取Jenkins管理员初始密码

    前言 最近在配置jenkins环境,但是启动jenkins后,进入jenkins解锁页时,需要自己获取初始密码. 尝试在访达中输入地址搜索,结果无该文件.后来百度上查看多篇文章后,终于获取到了初始密码 ...

  7. 鸟哥私房菜学习——centos 7_安装

    下面是我安装时遇到问题后搜索找到的可行办法: 准备工具: 8G左右U盘; 最新版UltraISO; CentOS7光盘镜像; CentOS7的镜像文件,可以在网易的开源镜像站或者阿里云的开源镜像站下载 ...

  8. python 按二维数组的某行或列排序 (numpy lexsort)

    lexsort支持对数组按指定行或列的顺序排序:是间接排序,lexsort不修改原数组,返回索引. (对应lexsort 一维数组的是argsort a.argsort()这么使用就可以:argsor ...

  9. Git004--版本回退

    Git--版本回退 本文来自于:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/ ...

  10. git团队协作代码提交步骤

    我们公司由五个人同时开发一个项目,大佬建好仓库后叫我们统一提交到dev这个分支,我的分支是hardy,你们只要将这两个值改成你们团队协作中使用的分支即可.代码如下: git add . git com ...