学习笔记--calling convention

这几天公司项目不忙,base公司某高手的ppt,小小研究了一下c++中的calling convention的相关内容。

 

1.什么是calling convention?

   中文译为调用约定。再细说就是在函数调用过程中,主调函数与被调函数之间的约定。如下func1就是主调函数,func2就是被调函数

    void func1()

    {

          func2(params);

    }

 

2.为什么要有调用约定?

   为了进行堆栈平衡。何谓堆栈平衡,函数在调用过程中,要对函数参数进行压栈操作,因此在函数调用之后,双方需要约定由谁来进行这些压栈操作的恢复。

 

3.都有哪些调用约定?

   _cdecl,_stdcall,thiscall,Fastcall etc,其中比较重要的是前两种。其中_cdecl约定为调用方进行堆栈平衡,_stdcall约定为被调方进行堆栈平衡。

 

介绍完了一些基本的概念,下面用一个例子来进一步说明问题:

 

C++代码非常简单:

void _stdcall test_convention(int a) //这里首先将函数声明为_stdcall,约定被调方,也就是被调函数进行堆栈平衡
{

    printf("%d,%d/n",a);
}

 

void main()
{
    test_convention(1);                       //test_convention就是被调函数
    system("pause");
}

 

程序生成的反汇编代码:

 test_convention(1);

//将变量1压栈
0041145E  push        1

//函数调用   
00411460  call        004111A4

F11跟进call之后的代码,反汇编如下:

void _stdcall test_convention(int a)
{
//***********此处省略若干行*********

//这句是关键,相当于ESP + 8(ret本身相当于+4),被调方进行堆栈平衡
0041141C  ret         4  

 

 

然后我们将函数的调用约定修改为_cdecl,约定为调用方进行堆栈平衡

void _cdecl test_convention(int a)

 test_convention(1);
0041144E  push        1   
00411450  call        0041119F

同样F11跟进去之后

//**********此处省略若干行**********

//只有一句ret

ret

 

//但在主调函数生成的汇编代码中,呵呵确实如此,调用方进行堆栈平衡
00411455  add         esp,4

 

至此为止,堆栈平衡的大概原理讲述完毕,如果想进一步深入的了解函数调用的汇编语言过程,不妨随便写个函数反汇编一下看看。

对了,如果你也像我一样是个菜鸟,不妨google一下ESP和EBP的意思,相信会对你有所帮助。

 

第一篇博客,值得纪念一下:)

 

2010-1-06 global_var

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值