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的更多相关文章

  1. 匈牙利命名法、骆驼命名法、帕斯卡(pascal)命名法 C#命名规范

    匈牙利命名法.骆驼命名法.帕斯卡(pascal)命名法 C#命名规范 一.匈牙利命名法:广泛应用于象Microsoft Windows这样的环境中. Windows 编程中用到的变量(还包括宏)的命名 ...

  2. Delphi中那些容易混淆的基础(@、^、Addr、Pointer,Move、CopyMemory,GetMem和FreeMem、GetMemory和FreeMemory、New和Dispose、StrAlloc和StrDispose、AllocMem)

    @.^.Addr.Pointer Delphi(Pascal)中有几个特殊的符号,如@.^等,弄清楚这些符号的运行,首先要明白Delphi指针的一些基础知识:指针,是一个无符号整数(unsigned ...

  3. .NET 基础 一步步 一幕幕[面向对象之方法、方法的重载、方法的重写、方法的递归]

    方法.方法的重载.方法的重写.方法的递归 方法: 将一堆代码进行重用的一种机制. 语法: [访问修饰符] 返回类型 <方法名>(参数列表){ 方法主体: } 返回值类型:如果不需要写返回值 ...

  4. .NET 基础 一步步 一幕幕 [注释、命名规则、访问修饰符、数据类型、常量、变量]

    注释.命名规则.访问修饰符.数据类型.常量.变量 话说一个不会写注释的程序猿的不是一个好吃货,我们本篇就从注释开始说起好了. 在C#中有三种注释: 第一种:单行注释  以//开头,后面的就是注释内容 ...

  5. python介绍、安装及相关语法、python运维、编译与解释

    1.python介绍 Python(英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/)是一种广泛使用的解释型.高级编程.通用型编程语言,由吉多.范罗苏姆创造,第一版发布于1991年.可以视 ...

  6. Delphi-基础(常量、集合、数组[动态数组、多维数组])

    一.常量 1.常量定义:一开始定义好的值,以后在程序的运行过程中不允许改变 const Pi : Double = 3.141592; //定义为常量 {常量的定义方式,可以不进行类型的声明,编译器会 ...

  7. Python全栈开发之3、深浅拷贝、变量和函数、递归、函数式编程、内置函数

    一.深浅拷贝 1.数字和字符串 对于 数字 和 字符串 而言,赋值.浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址. import copy # 定义变量 数字.字符串 # n1 = 123 n1 ...

  8. JavaScript学习笔记(一)——延迟对象、跨域、模板引擎、弹出层、AJAX示例

    一.AJAX示例 AJAX全称为“Asynchronous JavaScript And XML”(异步JavaScript和XML) 是指一种创建交互式网页应用的开发技术.改善用户体验,实现无刷新效 ...

  9. atitit.管理学三大定律:彼得原理、墨菲定律、帕金森定律

    atitit.管理学三大定律:彼得原理.墨菲定律.帕金森定律 彼得原理(The Peter Principle) 1 彼得原理解决方案1 帕金森定律 2 如何理解墨菲定律2 彼得原理(The Pete ...

随机推荐

  1. ExtJs Model之convert的使用

    convert: function(value,record){} value:为当前属性的值,record.get('属性')用来获取其他属性的值. 以下案例是:将年龄减去2. Ext.define ...

  2. 电子工程师名片——SPI NOR Flash

    使用了MX25L512的SPI接口的Flash 电路连接图: 总的大小512kb,即64kB,sector的大小为256 Bytes,block的大小为4k Bytes 调试时出现的问题: 1.Fla ...

  3. JavaScript 之 Cookie

    JavaScript是运行在客户端的脚本,因此一般是不能够设置Session的,因为Session是运行在服务器端的. 而cookie是运行在客户端的,所以可以用JS来设置cookie. 假设有这样一 ...

  4. Ajax下载文件(页面无刷新)

    说明:Ajax是无法实现文件传输的,本文只是模拟了Ajax不刷新页面就可以请求并返回数据的效果.实质上还是通过提交form表单来返回文件流的输出. 分步实现逻辑: ajax请求服务器,访问数据库,根据 ...

  5. 改变UITableViewCell按下去的颜色

    UIView *bgColorView = [[UIView alloc] init]; [bgColorView setBackgroundColor:[UIColor redColor]]; [c ...

  6. Android开发之Intent.Action

    1 Intent.ACTION_MAIN String: android.intent.action.MAIN 标识Activity为一个程序的開始.比較经常使用. Input:nothing Out ...

  7. linux下挂载iso镜像文件(转)

    挂接命令(mount) 首先,介绍一下挂接(mount)命令的使用方法,mount命令参数非常多,这里主要讲一下今天我们要用到的. 命令格式: mount [-t vfstype] [-o optio ...

  8. sql 成绩表 case then

    select * from  dbo.tb_Scroe select Name,(select count(*) from tb_Scroe where Name = t.Name and Scroe ...

  9. android学习---屏幕旋转

    /** *问题:今天学习android访问Servlet,Servlet给返回一个xml格式的字符串,android得到数据后将其显示到一个TextView中,发现Activity得到数据显 * 示到 ...

  10. C语言undefined behaviour未定义行为

    C语言中的未定义行为(Undefined Behavior)是指C语言标准未做规定的行为.同时,标准也从没要求编译器判断未定义行为,所以这些行为有编译器自行处理,在不同的编译器可能会产生不同的结果,又 ...