好了,可以讲讲大家熟悉的东西了

今天的第三部分,主要内容是x86平台上的32位调用约定。
这里先说明一下:今天的内容只会涵盖Windows操作系统或者Windows编程中涉及到的调用约定,没有关于其他操作系统或者特定于某个语言或者编译器厂商的内容。特别需要注意的是,如果尝试在C++中调用一个成员函数,则函数的第一个参数是一个”隐藏”的this指针。

All

所有在x86平台上的32位调用约定,都会保留EDI, ESI, EBP和EBX寄存器,并使用EDX:EAX寄存器对来返回值。

C(__cdecl)

32位的C调用约定上的约束限制和它的16位版本一样。参数从右至左入栈(所有,第一个参数会位于栈顶),并且调用者负责清栈。函数名称通过一个前置的下划线进行修饰。

__stdcall

这个调用约定主要用在Win32中,一个例外情况是可变参数的情况(可变参数将使用__cdecl),还有一些很少的函数会使用__fastcall。
参数从右至左入栈,被调用者负责清栈。函数名称通过一个前置下划线和指示参数字节数的结束字符(@-)来进行修饰。

__fastcall

在这种调用约定下,前面两个参数使用ECX和EDX来传递,剩余的参数则和__stdcall一样通过栈来传递。请注意,被调用者负责清栈。函数名称通过一个前置字符(@-)和一个指示参数字节数的结束字符(@-)来进行修饰。

thiscall

第一个参数(也就是上面提到的this指针)通过ECX传递,剩余的参数则通过栈来传递。被调用者负责清栈。函数名称被C++编译器使用了一种十分复杂的方式进行修饰,里面包含了每个参数的类型。

这个修饰手法十分有必要,因为它可以实现类似于函数重载的特性。也就是说:对于不同的重载的函数,C++编译器采用不同的名称进行修饰,以区分它们。

总结

调用约定,说白了,就是调用者和被调用者之间的一种合约。

如果你编写汇编代码,则调用约定意味着:你编写的回调函数需要保留调用约定所规定的寄存器,因为调用者(可能是操作系统本身)依赖于它。

举例来说,如果在一次函数中EBX寄存器中的数据搞乱了,那么就会出现不符合预期的行为,这个时候,请不要感到惊讶。后面我们会有关于这个主题的更多内容,敬请期待。

最后

Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《The history of calling conventions, part 3》

c++ 调用windows tts_有关调用约定的历史 – 第三部分相关推荐

  1. C#调用windows api的要点

    在.Net Framework SDK文档中,关于调用Windows API的指示比较零散,并且其中稍全面一点的是针对Visual Basic .net讲述的.本文将C#中调用API的要点汇集如下,希 ...

  2. C#中调用Windows API的要点

    在.Net Framework SDK文档中,关于调用Windows API的指示比较零散,并且其中稍全面一点的是针对Visual Basic .net讲述的.本文将C#中调用API的要点汇集如下,希 ...

  3. C#中调用Windows API的要点【转载】

    在.Net Framework SDK文档中,关于调用Windows API的指示比较零散,并且其中稍全面一点的是针对Visual Basic .net讲述的.本文将C#中调用API的要点汇集如下,希 ...

  4. [收集]Visual C#中调用Windows API

    在.Net Framework SDK文档中,关于调用Windows API的指示比较零散,并且其中稍全面一点的是针对Visual Basic .net讲述的.本文将C#中调用API的要点汇集如下,希 ...

  5. 使用C#调用windows API

    使用C#调用windows API(从其它地方总结来的,以备查询) C#调用windows API也可以叫做C#如何直接调用非托管代码,通常有2种方法: 1.  直接调用从 DLL 导出的函数. 2. ...

  6. C#中调用Windows API时的数据类型对应关系

    C#中调用Windows API时的数据类型对应关系 原文 C#中调用Windows API时的数据类型对应关系 BOOL=System.Int32 BOOLEAN=System.Int32 BYTE ...

  7. 在c#中调用windows脚本的方法

    在c#中调用windows脚本的方法 方法1:直接调用   CODE:   System.Diagnostics.Process proc = new System.Diagnostics.Proce ...

  8. 用C#调用Windows API向指定窗口发送按键消息

    为什么80%的码农都做不了架构师?>>>    用C#调用Windows API向指定窗口发送 一.调用Windows API. C#下调用Windows API方法如下: 1.引入 ...

  9. Windows恶意软件API调用特征分析

    本文讲的是Windows恶意软件API调用特征分析, 1.背景 目标: 1)找到病毒调用概率高的API 2)找到病毒调用概率不高,但是当调用频次高的时候,是病毒概率高的API. 通常对病毒使用API的 ...

  10. 如何在Python中调用Windows的cmd命令?

    简 介: 利用os,commands,subprocess模块可以在python中调用windows中的命令.从使用方便性上来看,利用os.popen可以执行windows的程序并可以获得返回内容. ...

最新文章

  1. Windows系统一键安装zabbix agent
  2. intellijidea课程 intellijidea神器使用技巧 3-1 列操作
  3. C#通过COM组件操作IE浏览器(二):使用IHTMLDocument3完成登录
  4. springboot + kafka
  5. 很好用的ISO制作软件
  6. net.sf.ezmorph.Morpher问题解决
  7. 算法设计之0-1背包问题
  8. Vue keep-alive实践总结
  9. Redis集群之主从复制
  10. MySQL数据库分布式事务XA实现原理分析
  11. 数据结构课程设计c语言运动会管理系统
  12. java制作视频播放器
  13. C双拼输入法使用说明
  14. RDT 协议 (可靠数据传输协议)
  15. UE4 GamePlay架构
  16. SAP 领料BAPI BAPI_GOODSMVT_CREATE 提示 短缺未限制使用的SL
  17. mysql forward_only_mysql参数调优
  18. 虚拟机怎么连云服务器,虚拟机怎么连接云服务器
  19. linux报ora12560,测试ORA-12560和ORA-12500
  20. java基础之package和import语句

热门文章

  1. 众信金融8·28开放日:聆听投资人心声
  2. 自定义百度网盘提取码
  3. 【Elasticsearch】Mapping APIs
  4. 使用Sublime Text 2 编辑Markdown
  5. OSPF配置末梢区域
  6. php采集过滤内容,PHP采集利器:根据开始字符串和结束字符串截取需要的采集内容数据...
  7. 系统开机 linux 时间不对,linux下查看系统运行时间和最近一次的开机启动时间
  8. Android实现计算器布局(表格布局)
  9. 手机开机显示设备服务器信息,原 live-server启动一个本地服务器(手机访问)
  10. 基于FormsAuthentication的用户、角色身份认证