zoukankan      html  css  js  c++  java
  • __stdcall、__cdcel和__fastcall

    __stdcall__cdecl__fastcall是三种函数调用协议,函数调用协议会影响函数参数的入栈方式、栈内数据的清除方式、编译器函数名的修饰规则等。

      在win32应用程序里,宏APIENTRY,WINAPI,都表示_stdcall。


    调用协议常用场合
    __stdcall:Windows API默认的函数调用协议。
    __cdecl:C/C++默认的函数调用协议。
    __fastcall:适用于对性能要求较高的场合。


    函数参数入栈方式
    __stdcall:函数参数由右向左入栈。
    __cdecl:函数参数由右向左入栈。
    __fastcall:从左开始不大于4字节的参数放入CPU的ECX和EDX寄存器,其余参数从右向左入栈。


    C语言编译器函数名称修饰规则
    __stdcall:编译后,函数名被修饰为“_functionname@number”。
    __cdecl:编译后,函数名被修饰为“_functionname”。
    __fastcall:编译后,函数名给修饰为“@functionname@nmuber”。
    注:“functionname”为函数名,“number”为参数字节数。函数实现和函数定义时如果使用了不同的函数调用协议,则无法实现函数调用


    C++语言编译器函数名称修饰规则
    __stdcall:编译后,函数名被修饰为“?functionname@@YG******@Z”。
    __cdecl:编译后,函数名被修饰为“?functionname@@YA******@Z”。
    __fastcall:编译后,函数名被修饰为“?functionname@@YI******@Z”。
    注:“**”为函数返回值类型和参数类型表。函数实现和函数定义时如果使用了不同的函数调用协议,则无法实现函数调用。C语言和C++语言间如果不进行特殊处理,也无法实现函数的互相调用。


    __stdcall
    __stdcall是Pascal方式清理C方式压栈,通常用于Win32 Api中,函数采用从右到左的压栈方式,自己在退出时清空堆栈。VC将函数编译后会在函数名前面加上下划线前缀,在函数名后加上”@”和参数的字节数。 int f(void *p) –>> _f@4(在外部汇编语言里可以用这个名字引用这个函数).


    __cdecl
    __cdecl (The C default calling convention)即C调用约定按从右至左的顺序压参数入栈,由调用者把参数弹出栈。对于传送参数的内存栈是由调用者来维护的。另外,在函数名修饰约定方面也有所不同。 _cdecl是C和C++程序的缺省调用方式。每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。


    __fastcall
    __fastcall调用的主要特点就是快,因为它是通过寄存器来传送参数的(实际上,它用ECX和EDX传送前两个双字(DWORD)或更小的参数,剩下的参数仍旧自右向左压栈传送,被调用的函数在返回前清理传送参数的内存栈),在函数名修饰约定方面,它和前两者均不同。__fastcall方式的函数采用寄存器传递参数,VC将函数编译后会在函数名前面加上”@”前缀,在函数名后加上”@”和参数的字节数。

  • 相关阅读:
    网页一屏到底有多大 1024*768 800*600 网页设计大小 网页设计尺寸
    去掉VS2005中水晶报表的登录界面(ZT)
    Visual Studio 2005 IDE 技巧和窍门
    asp.net大页面载入时以进度条显示zt
    从webservice读取string[]至downlist,增加onchange事件,更改相关显示。
    在asp.net Sql server (可以是存储过程)中使用事务回滚
    得到页面所有的form内对象数值——————为一个控件加一个客户端属性
    Agile Web Development 4th ed. Can't mass assign.error
    Ubuntu12.04中安装和配置Java JDK(转)
    Javascript没有块级作用域
  • 原文地址:https://www.cnblogs.com/laohaozi/p/12538381.html
Copyright © 2011-2022 走看看