cdecl、pascal、stdcall、fastcall
Directive Parameter order Clean-up Passes parameters in registers?
register Left-to-right Routine Yes
pascal Left-to-right Routine No
cdecl Right-to-left Caller No
stdcall Right-to-left Routine No
safecall Right-to-left Routine No
调用约定 压参数入栈顺序 把参数弹出栈者 函数修饰名
(Calling convention)
--------------------------------------------------------------------------------------------------------
__cdecl 右->左 调用者 _function
__fastcall 右->左 被调用者 @function@nnn
__stdcall 右->左 被调用者 _function@nnn
__pascal 左->右 被调用者 _function@nnn
-----------------------------------------------------------------------------------------------------------
__cdecl是C/C++和MFC程序默认使用的调用约定,也可以在函数声明时加上__cdecl关键字来手工指定。采用__cdecl约定时,函数参数按照从右到左的顺序入栈,并且由调用函数者把参数弹出栈以清理堆栈。因此,实现可变参数的函数只能使用该调用约定。由于每一个使用__cdecl约定的函数都要包含清理堆栈的代码,所以产生的可执行文件大小会比较大。__cdecl可以写成_cdecl。
__stdcall调用约定用于调用Win32 API函数。采用__stdcal约定时,函数参数按照从右到左的顺序入栈,被调用的函数在返回前清理传送参数的栈,函数参数个数固定。由于函数体本身知道传进来的参数个数,因此被调用的函数可以在返回前用一条ret n指令直接清理传递参数的堆栈。__stdcall可以写成_stdcall。
__fastcall约定用于对性能要求非常高的场合。__fastcall约定将函数的从左边开始的两个大小不大于4个字节(DWORD)的参数分别放在ECX和EDX寄存器,其余的参数仍旧自右向左压栈传送,被调用的函数在返回前清理传送参数的堆栈。__fastcall可以写成_fastcall。
·特别说明
1. 在默认情况下,采用__cdecl方式,因此可以省略.
2. WINAPI一般用于修饰动态链接库中导出函数
3. CALLBACK仅用于修饰回调函数
便于更好理解, 看下面例子(函数调用的过程以汇编代码表示):
void cdecl fun1(int x,int y);
void stdcall fun2(int x,int y);
void pascal fun3(int x,int y);
****************************************
void cdecl fun1(int x,int y);
fun1(x,y);
调用 fun1 的汇编代码
push y
push x
call fun1
add sp,sizeof(x)+sizeof(y) ;跳过参数区(x,y)
fun1 的汇编代码:
fun1 proc
push bp
mov bp,sp
……
…
pop bp
ret ;返回,但不跳过参数区
fun1 endp
****************************************
void stdcall fun2(int x,int y);
fun2(x,y);
调用 fun2 的汇编代码
push y
push x
call fun2
fun2 的汇编代码:
fun2 proc
push bp
mov bp,sp
……
…
pop bp
ret sizeof(x)+sizeof(y) ;返回并跳过参数区(x,y)
fun2 endp
*****************************************
void pascal fun3(int x,int y);
fun3(x,y);
调用 fun3 的汇编代码
push x
push y
call fun3
fun3 的汇编代码:
fun3 proc
push bp
mov bp,sp
……
…
pop bp
ret sizeof(x)+sizeof(y) ;返回并跳过参数区(x,y)
fun3 endp
cdecl、pascal、stdcall、fastcall的更多相关文章
- 匈牙利命名法、骆驼命名法、帕斯卡(pascal)命名法 C#命名规范
匈牙利命名法.骆驼命名法.帕斯卡(pascal)命名法 C#命名规范 一.匈牙利命名法:广泛应用于象Microsoft Windows这样的环境中. Windows 编程中用到的变量(还包括宏)的命名 ...
- Delphi中那些容易混淆的基础(@、^、Addr、Pointer,Move、CopyMemory,GetMem和FreeMem、GetMemory和FreeMemory、New和Dispose、StrAlloc和StrDispose、AllocMem)
@.^.Addr.Pointer Delphi(Pascal)中有几个特殊的符号,如@.^等,弄清楚这些符号的运行,首先要明白Delphi指针的一些基础知识:指针,是一个无符号整数(unsigned ...
- .NET 基础 一步步 一幕幕[面向对象之方法、方法的重载、方法的重写、方法的递归]
方法.方法的重载.方法的重写.方法的递归 方法: 将一堆代码进行重用的一种机制. 语法: [访问修饰符] 返回类型 <方法名>(参数列表){ 方法主体: } 返回值类型:如果不需要写返回值 ...
- .NET 基础 一步步 一幕幕 [注释、命名规则、访问修饰符、数据类型、常量、变量]
注释.命名规则.访问修饰符.数据类型.常量.变量 话说一个不会写注释的程序猿的不是一个好吃货,我们本篇就从注释开始说起好了. 在C#中有三种注释: 第一种:单行注释 以//开头,后面的就是注释内容 ...
- python介绍、安装及相关语法、python运维、编译与解释
1.python介绍 Python(英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/)是一种广泛使用的解释型.高级编程.通用型编程语言,由吉多.范罗苏姆创造,第一版发布于1991年.可以视 ...
- Delphi-基础(常量、集合、数组[动态数组、多维数组])
一.常量 1.常量定义:一开始定义好的值,以后在程序的运行过程中不允许改变 const Pi : Double = 3.141592; //定义为常量 {常量的定义方式,可以不进行类型的声明,编译器会 ...
- Python全栈开发之3、深浅拷贝、变量和函数、递归、函数式编程、内置函数
一.深浅拷贝 1.数字和字符串 对于 数字 和 字符串 而言,赋值.浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址. import copy # 定义变量 数字.字符串 # n1 = 123 n1 ...
- JavaScript学习笔记(一)——延迟对象、跨域、模板引擎、弹出层、AJAX示例
一.AJAX示例 AJAX全称为“Asynchronous JavaScript And XML”(异步JavaScript和XML) 是指一种创建交互式网页应用的开发技术.改善用户体验,实现无刷新效 ...
- atitit.管理学三大定律:彼得原理、墨菲定律、帕金森定律
atitit.管理学三大定律:彼得原理.墨菲定律.帕金森定律 彼得原理(The Peter Principle) 1 彼得原理解决方案1 帕金森定律 2 如何理解墨菲定律2 彼得原理(The Pete ...
随机推荐
- SQL Server索引语法 <第四篇>
从CREATE开始 通过显式的CREATE INDEX命令 在创建约束时作为隐含的对象 随约束创建的隐含索引 当向表中添加如下两种约束之一时,就会创建隐含索引. 主键约束(聚集索引) 唯一约束(唯一索 ...
- Asp.NET MVC 技术参考:http://kb.cnblogs.com/zt/mvc/
Asp.NET MVC 技术参考:http://kb.cnblogs.com/zt/mvc/
- UVA 10129-Play on Words(欧拉通路)
题意:给N个单词,判断是否单词首尾(前一个单词的尾字符与后一个单词的头字符相同)相连能否形成一条链. 解析:找欧拉通路(欧拉回路或是欧拉链路),但这题事先需要并查集一下,判断是否只属于一个集合,如aa ...
- windows多线程没那么难
windows多线程没那么难 作者:vpoet mail:vpoet_sir@163.com 上一博文中我们引入了CreateThread()多线程编程一个简单的例子,事实上我说windows 多线程 ...
- OpenWrt backfire trunk源码下载及编译
OpenWrt signature check failed remove wrong signature file svn co svn://svn.openwrt.org/openwrt/bran ...
- 安装配置MongoDB数据库
一.关闭SElinux.配置防火墙 1.vi /etc/selinux/config #SELINUX=enforcing #注释掉 #SELINUXTYPE=targeted #注释掉 SELINU ...
- 在Android中建立Android project没有R.java文件
最近在搞一下安卓,在新建Android工程,既然发现在gen目录下没有R.java这个文件.我当时感到很郁闷,上次建Android工程才好好的,怎么这次既然报错没有R.java.后来我用以下才解决了. ...
- git使用经验
一直想写一点关于git的文章,但是平时太懒了,没有写,现在写些经验这里,方便以后自己忘记了.
- Alter的用法(添加字段,删除字段,修改字段名)
1.在表emp中新增字段sexy(性别) alter table emp add sexy varchar2(2); 新增多个字段cxx 和shoneworn alter table emp add ...
- commands - `ls`
list only directories: ls -d /path/to/*/