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. SSH移植

    1. 下载需要的源码,直接google最新的版本吧 mkdir -p ~/arm/fs ;mkdir -p ~/arm/source 下载zlib: zlib-1.2.3.tar.gz 下载ssl : ...

  2. Atom列编辑快捷键

    安装这个:sublime-style-column-selection,在Ubuntu下使用[Shitf]+鼠标左键选择.

  3. ArcEngine影像图配准

    转自原文ArcEngine影像图配准 影像图配准主要包括以下几个方面 1.打开影像图 2.配准 3.影像图入库/保存 1.打开影像图的代码以前已经写过了. 2.配准   配准 主要使用IGeoRefe ...

  4. markdown 插入latex公式练习

    markdown 插入latex公式 $$公式$$表示行间公式,本来Tex中使用\(公式\)表示行内公式,但因为Markdown中\是转义字符,所以在Markdown中输入行内公式使用\\(公式\\) ...

  5. CentOS 6.x Radius

    CentOS 6.x Radius 一.   实现环境: 1.系统:CentOS  release  6.6 (Final) 2.需要软件包: 1) freeradius-2.1.12-6.e16.x ...

  6. 编程基础知识——Java JNI开发流程(2)

    android中使用jni调用本地C++库 android平台上的本地库文件后缀 .so.类似windows上的dll文件. 要在android上使用jni.首先须要下载android ndk. 操作 ...

  7. Nginx在Linux下的安装部署

    Nginx简单介绍 Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 server,也是一个 IMAP/POP3/SMTP server.Nginx作为 ...

  8. 论持久战之PHPStorm Xdebug Remote 调试环境搭建(不依赖本地环境)

    最近公司自己搭建了一个资源管理平台,哈哈,当然是我在github上找的,后台用PHP开发.个人觉得写得非常nice,web页面几乎模拟了真实OS,有兴趣的朋友下载部署体验https://github. ...

  9. Thinkpad升级Window10无法安装expresscache

    本人有一台Thinkpad T440s,自从看了这篇帖子12秒开机!ExpressCache SSD缓存加速,就给自己的小黑加持了一块固态硬盘.使用后效果确实很明显. 问题 自从系统自动升级到wind ...

  10. Java SE之break和continue标签

    文是学习网络上的文章时的总结,感谢大家无私的分享. Java没有提供goto功能,可是保留了gotokeyword. 在java中能够使用break标签和continue标签功能实现简版的goto功能 ...