__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. 解决Win7部分便笺的元数据已被损坏的方法

    Win7部分便笺的元数据已被损坏的方法 我们使用键盘上"Win+F"组合键搜索功能,直接找到"inkobj.dll"这个文件,一般会搜索出来好多,先随便选一个. ...

  2. RSA - 原理、特点(加解密及签名验签)及公钥和私钥的生成

    Wiki - RSA加密演算法 Wiki - 欧拉函数 Wiki - 模反元素 ASN.1 格式标准 RSA算法原理(二) 注意: RSA 加密或签名后的结果是不可读的二进制,使用时经常会转为 BAS ...

  3. nmon分析工具的使用

    linux监控服务器资源 1.下载nmon_linux_more_14g.tar.gz,下载完成解压之后,我们先命令行看看自己Linux的版本,和nmon支持一下Linux发行版本 2.mkdir / ...

  4. 20190823 尚硅谷MySQL核心技术

    背景 视频时间:2017.09 MySQL版本:5.5 MySQL基础 命令行启动.停止MySQL: net start MySQL(这里是注册的服务名称) net stop MySQL 命令行连接M ...

  5. servlet--禁用浏览器缓存

    禁用浏览器缓存:Cache-Control.pragma.expires response.setHeader("Cache-Control", "no-cache&qu ...

  6. [eclipse中使用Git插件] 008 - git操作pull、merge、stash、commit

    写在前面: 看标题其实还有001-007之类,本来准备写详细的类似教程一样的东东,但是懒了且时间有限(以后或许会补吧),所以跳到008,录下主要的操作. 所以本随笔的重点就是[pull+merge+s ...

  7. JS的两种函数声明方式的区别

    ---恢复内容开始--- js中常见的两种函数声明方式如下: // 函数表达式 var f = function() { console.log(1); } // 直接声明 function f () ...

  8. vue基础介绍及使用

    1.vue基本使用 vm:el / data v:v-model / {{ }} 1. 引入Vue.js 2. 创建Vue对象 el : 指定根element(选择器) data : 初始化数据(页面 ...

  9. [已解决]报错: warning: LF will be replaced by CRLF in lib/anime.min.js

    git config --global core.autocrlf false

  10. Java并发编程:线程的创建

    Java并发编程:线程的创建 */--> code {color: #FF0000} pre.src {background-color: #002b36; color: #839496;} J ...