函数的调用过程(栈帧)

   

        我们知道每次函数调用都是一个过程,这个过程称之为函数的调用过程。且每次函数调用都要为本次函数调用开辟栈空间,

  用于本次函数的调用中临时变量的保存、现场保护。这块栈空间我们称之为函数栈帧


   那又怎样维护这块空间呢?这块空间的上限在哪里、下限又在哪里?

   这里就涉及两个寄存器(ebpesp,在函数的调用过程中这两个寄存器存放了维护这个栈的栈低和栈顶指针。

     ebp存放了指向函数栈帧栈底的地址。
     esp存放了指向函数栈帧栈顶的地址。

    注:栈空间的使用是由高地址向底地址,所以越是低的地址越是靠后入栈


现在深入的研究一下函数的调用过程

  先看下面这段代码:

      

   当进行程序调试的时候,查看【函数堆栈】,会出现如下:

     

 

   由此,我们可以发现main函数在__tmainCRTStartup函数中调用,而__tmainCRTStartup函数在mainCRTStartup函数中被调用。


当我们详细研究函数的栈帧调用,必须对应反汇编代码

   1.  从main函数开始,先来看main函数栈帧的创建

    

     

    2. 接下来是add函数的调用

        参数传递过程

       

      这里需要注意的是call指令的调用。

      

        执 行call指令时按F11,来到这里,

      

      

        再按F11就进入Add函数的执行代码处

        

            这里需要注意返回结果保存在eax寄存器中,

            再然后,就是函数的返回部分

       

              这里需要注意ret指令,

整个过程的图解如下

 


例题:

   利用上面的知识,看一下在VC6.0环境中,下面代码的结果是什么?

 

 

 结果为:20

 原因:仿照上面函数的调用过程,不难理解,*(&tmp+1)正好为main函数的栈低地址,即p(main-esp),整形指针加(或减)1,跳过4个字节,则p-1a变量空间地址,即*p-1=20,改变了a变量的值,所以输出结果为20.


 

    


    

  


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值