Microsoft函数调用约定

对于所有调用共有的约定:ebx、ebp、esi、edi都是calle-save,即由被调用的函数负责它们的保存(如果被调用函数用到了这些寄存器的话)

先看函数调用发生了什么:(win32下)
1、所有参数提升到4bytes的倍数
2、执行call指令
3、将ebx、ebp、esi、edi保存在栈上,这一步称为function prolog
4、将返回值放在eax中(返回int64放在edx:eax中,返回double放在浮点寄存器中。复杂的数据结构在caller的栈中分配空间,将首地址做为最后压栈的参数(我拿__cdecl试的),callee返回的时候将返回值放在这个指针指向的地址)
5、取出ebx、ebp、esi、edi,这一步称为function epilog
6、清空栈,保持堆栈平衡,这一步称为stack cleanup

具体的调用约定:
1、__cdecl
压栈顺序:从右至左
清栈:函数调用者负责清空,称为caller cleanup
名字修饰(name decoration):在函数名前加上下划线做前缀,比如_foo
注:c/c++函数的缺省调用约定

2、__stdcall
压栈顺序:从右至左
清栈:被调用函数负责清空,称为callee cleanup
名字修饰:在函数名前加上下划线做前缀,名字后用@加上函数参数大小做后缀,如_foo@8
注:WINAPI就是__stdcall的#define

3、__fastcall
压栈顺序:第一个参数放在ecx,第二个参数放在edx,其余从右至左
清栈:callee cleanup
名字修饰:在函数名前加上@做前缀,名字后用@加上函数参数大小做后缀,如@foo@8
注:名字叫fast实际就不一定了……

4、thiscall
压栈顺序:this指针(cpp非静态成员函数特有)放在ecx,其余从右至左
清栈:callee cleanup
注:cpp非静态成员函数默认的调用约定

5、naked
压栈顺序:从右至左
清栈:caller cleanup
注:VxDs用的调用约定,将__declspec(naked)写在函数定义处(注意,不是声明)

这篇文章把naked作为calling convention: http://www.cs.cornell.edu/courses/cs412/2001sp/resources/microsoft-calling-conventions.htm

但naked应该算不上调用约定了,只是单纯地将c/c++代码翻译成asm,连esp、ebp之间的保存、mov都没有就直接拿ebp来寻址了,函数结束后也不管ret,太naked了!

补充:c允许可变参数(例如printf),为了方便地使用这些函数,所以__cdecl要
1、从右至左压栈(这样才能知道第一个参数在堆栈中的地址)
2、caller cleanup(因为只有caller才知道这次调用push了多少参数

函数调用约定的历史——16位的世界:

对所有的调用约定:
1、用dx:ax或ax保存返回值
2、由于cx不能寻址,所以还需要一个bx来scratch(就是不需要callee-save的寄存器)

具体的调用约定
1、__cdecl
名字修饰在函数前加下划线可能是为了区别函数名和汇编语言的关键字

2、__pascal
自左至右传参、callee cleanup
比较有意思的是名字修饰把函数名转换为大写,嗯,pascal大小写无关……
几乎所有的win16函数都是用pascal调用约定,因为callee-clean的操作比caller-clean要节省3bytes的空间

3、__fortran
和pascal一样

4、__fastcall
和win32下一样,把ecx、edx换为cx、dx罢了
这个fast可是未必,如果函数中的计算要用到cx、dx就免不了把cx、dx压栈的操作了,所以这种调用约定仅仅可能对短小的leaf function(就是不调用其他函数的函数)快一些,甚至对这类函数都快不了……

 

Microsoft函数调用约定的更多相关文章

  1. C语言函数调用约定

    在C语言中,假设我们有这样的一个函数: int function(int a,int b) 调用时只要用result = function(1,2)这样的方式就可以使用这个函数.但是,当高级语言被编译 ...

  2. 函数调用约定_stdcall[转]

    关键字 清理堆栈 参数入栈顺序 函数名称修饰(C) __cdecl 调用函数 右 à 左 _函数名 __stdcall 被调用函数 右 à 左 _函数名@数字 __fastcall 被调用函数 右 à ...

  3. Windows x64汇编函数调用约定

    最近在写一些字符串函数的优化,用到x64汇编,我也是第一次接触,故跟大家分享一下. x86:又名 x32 ,表示 Intel x86 架构,即 Intel 的32位 80386 汇编指令集. x64: ...

  4. 【黑客免杀攻防】读书笔记7 - 软件逆向工程基础1(函数调用约定、Main函数查找)

    0x1 准备工作 1.1.准备工具 IDA:交互式反汇编工具 OllyDbg:用户层调试工具 Visual Studio:微软开发工具 1.2.基础知识 C++开发 汇编语言 0x2 查找真正的mai ...

  5. 汇编  cdecl 函数调用约定,stdcall 函数调用约定

    知识点:  cdecl 函数调用约定  stdcall 函数调用约定  CALL堆栈平衡 配置属性--> c/c++ -->高级-->调用约定 一.cdecl调用约定 VC++ ...

  6. 关于函数调用约定-thiscall调用约定

    函数调用约定描述了如何以正确的方式调用某些特定类型的函数.包括了函数参数在栈上的分配顺序.有哪些参数将通过寄存器传入,以及在函数返回时函数栈的回收方式等. 函数调用约定的几种类型 stdcall,cd ...

  7. C/C++函数调用约定与this指针

    关于 C/C++ 函数调用约定,大多数时候并不会影响程序逻辑,但遇到跨语言编程时,了解一下还是有好处的. VC 中默认调用是 __cdecl 方式,Windows API 使用 __stdcall 调 ...

  8. c++中的几种函数调用约定(转)

    C++中的函数调用约定(调用惯例)主要针对三个问题: 1.参数传递的方式(是否采用寄存器传递参数.采用哪个寄存器传递参数.参数压桟的顺序等): 参数的传递方式,最常见的是通过栈传递.函数的调用方将参数 ...

  9. 关于 C/C++ 函数调用约定

    关于 C/C++ 函数调用约定,大多数时候并不会影响程序逻辑,但遇到跨语言编程时,了解一下还是有好处的. VC 中默认调用是 __cdecl 方式,Windows API 使用 __stdcall 调 ...

随机推荐

  1. html页面中拍照和上传照片那些事儿(一)

    本文为原创,转载请注明出处: cnzt  文章:cnzt-p http://www.cnblogs.com/zt-blog/p/6709037.html  一. 思路: <input type= ...

  2. apc smart UPS下使用apcupsd注意事项

    公司的apc smart UPS安装有管理卡(似乎是AP-9631),server环境有FreeBSD.Windows Server.Linux(CentOS.Ubuntu) 实际使用中有例如以下问题 ...

  3. SpringMVC+Hibernate+Junit4+json基本框架近乎0配置

    公司是做APP开发的,须要后台来提供接口,于是乎,这个任务就交给我,经过重复的尝试,学习和參考别人的demo,最终搭出自己还算惬意的框架.SpringMVC+Sping3+Hibernate4+Jun ...

  4. 湘潭邀请赛——Alice and Bob

    Alice and Bob Accepted : 133   Submit : 268 Time Limit : 1000 MS   Memory Limit : 65536 KB  Problem ...

  5. 【Mongodb教程 第一课 补加课1 】windows7 下安装mongodb 开启关闭服务

    mongodb在2.2版本开始就不支持windows xp了(我想现在用xp的应该也是带着情怀的一部分人吧,我只是一个工匠而已),windows下server8 R2,64位,32位,只是32位只支持 ...

  6. c# 把一个匿名对象赋值给一个Object类型的变量后,怎么取这个变量? c# dynamic动态类型和匿名类 详解C# 匿名对象(匿名类型)、var、动态类型 dynamic 深入浅析C#中的var和dynamic

    比如有一个匿名对象,var  result =......Select( a=>new {  id=a.id, name=a.name});然后Object  obj =  result ;我怎 ...

  7. Jenkins系列之-—04 配置用户和权限控制

    一.安装插件 插件名称:Role-based Authorization Strategy Role Strategy Plugin插件可以对构建的项目进行授权管理,让不同的用户管理不同的项目. 二. ...

  8. 小胖说事35-----Terminating app due to uncaught exception &#39;CALayerInvalidGeometry&#39;, reason: &#39;CALayer posi

    2011-06-11 15:19:17.167 ***[930:707] *** Terminating app due to uncaught exception 'CALayerInvalidGe ...

  9. IE9版本号下面ajax 跨域问题解决

    ajax跨域请求数据在谷歌火狐我本地IE11都是没问题的. 让測试就发现问题了,IE8下请求不到数据.然后我查看一下自己写的js看有没有不兼容问题.但是都没有啊.为什么就请求不到呢. 我把ajax的e ...

  10. 机器学习和深度学习笔记(Matlab语言实现)

    不多说,直接上干货! 这里,对于想用matlab语言来做的朋友,强烈推荐 http://www.cnblogs.com/tornadomeet/