设为首页 加入收藏

TOP

C/C++函数调用的几种方式
2012-11-01 15:44:55 来源: 作者: 【 】 浏览:374
Tags:C/C 函数 调用 方式

    我们知道,调用函数时,计算机常用栈来存放函数执行需要的参数,由于栈的空间大小是有限的,在windows下栈是向低地址扩展的数据结构,是一块连续的内存区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,windows下栈的大小是2M(也有的说是1M),如果申请的空间超过栈的剩余空间时,将提示overflow.

    在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。

    在参数传递中,有两个重要的问题必须要明确说明:

    1. 当参数个数多于一个时,按照什么顺序把参数压入堆栈;

    2. 函数调用后,由谁来把堆栈恢复原状。

    在高级语言中,就是通过函数的调用方式来说明这两个问题的。常见的调用方式有:

    stdcall

    cdecl

    fastcall

    thiscall

    thiscall

    naked call

    下面就分别介绍这几种调用方式:

    1. stdcall

    stdcall调用方式又被称为Pascal调用方式。在Microsoft C++(www.cppentry.com)系列的C/C++(www.cppentry.com)编译器中,使用PASCAL宏,WINAPI宏和CALLBACK宏来指定函数的调用方式为stdcall.

    stdcall调用方式的函数声明为:

    int _stdcall function(int a, int b);

    stdcall的调用方式意味着:

    (1) 参数从右向左依次压入堆栈

    (2) 由被调用函数自己来恢复堆栈

    (3) 函数名自动加前导下划线,后面紧跟着一个@,其后紧跟着参数的尺寸

    上面那个函数翻译成汇编语言将变成:

    push b 先压入第二个参数

    push a 再压入第一个参数

    call function 调用函数

    在编译时,此函数的名字被翻译为_function@8.

    __cdecl调用约定仅在输出函数名前加上一个下划线前缀,格式为_function.

    __fastcall调用约定在输出函数名前加上一个"@"符号,后面也是一个"@"符号和其参数的字节数,格式为@function@8.

    它们均不改变输出函数名中的字符大小写,这和PASCAL调用约定不同,PASCAL约定输出的函数名无任何修饰且全部大写。

    2. C++(www.cppentry.com)编译时函数名修饰约定规则:

    __stdcall调用约定:

    (1)以" "标识函数名的开始,后跟函数名;

    (2)函数名后面以"@@YG"标识参数表的开始,后跟参数表;

    (3)参数表以代号表示:

    X--void ,

    D--char,

    E--unsigned char,

    F--short,

    H--int,

    I--unsigned int,

    J--long,

    K--unsigned long,

    M--float,

    N--double,

    _N--bool,

    …

    PA--表示指针,后面的代号表明指针类型,如果相同类型的指针连续出现,以"0"代替,一个"0"代表一次重复;

    (4)参数表的第一项为该函数的返回值类型,其后依次为参数的数据类型,指针标识在其所指数据类型前;

    (5)参数表后以"@Z"标识整个名字的结束,如果该函数无参数,则以"Z"标识结束。

    其格式为" functionname@@YG*****@Z"或" functionname@@YG*XZ",例如

    int Test1(char *var1,unsigned long)-----" Test1@@YGHPADK@Z"

    void Test2() -----" Test2@@YGXXZ"

    __cdecl调用约定:

    规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的"@@YG"变为"@@YA".

    __fastcall调用约定:

    规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的"@@YG"变为"@@YI".

    VC++(www.cppentry.com)对函数的省缺声明是"__cedcl",将只能被C/C++(www.cppentry.com)调用。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C++函数间数据传递方式 下一篇C++ 多线程编程总结

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: