【C语言初阶】函数栈帧的创建和销毁

以下都是在VS2013环境下实现的,在不同的编译器下函数的栈帧创建略有不同。

1.寄存器:eax、ebx、ecx、edx等等。

与函数栈帧相关的寄存器有ebp(栈底指针)、esp(栈顶指针),这两个寄存器是来维护函数栈帧的。

2.在VS2013中,main函数也是被其他函数调用的

mainCRTStartup   --->   __tmainCRTStartup   --->   main

3.函数栈帧创建与销毁的过程

具体过程以下边的代码为例

#include <stdio.h>

int Add(int x,int y)
{
    int z=0;
    z=x+y;
    return z;
}

int main()
{
    int a=10;
    int b=20;
    int c=0;

    c=Add(a,b);
    
    printf(%d\n",c);

    return 0;
}

当程序运行后转到反汇 编,通过反汇编观察程序的运行

 1.push            ebp                                       将ebp的值压栈

 2.mov             ebp,esp                                将esp的值传给edp

 3.sub              esp,0E4h                              esp-0E4h(相当于给main函数预留了一段空间)

 4.push            ebx                                       将ebx的值压栈

 5.push            esi                                        将esi的值压栈

 6.push            edi                                        将edi的值压栈

 7.lea               edi                                        edi,[ebp+FFFFFF1Ch](加载有效地址,将 [ ] 中的地址加载到edi中)

                                                                    该地址为,[ebp-0E4h](此地址是第三行的值)

 8.mov             ecx,39h                                将39h这个值放入ecx中

 9.mov             eax,0CCCCCCCCh             eax中加入0CCCCCCCCh中

10.rep stos      dword ptr es:[edi]                 从第7到9行,从edi地址开始向下ecx个的double字(4字节)全部变成eax中的值

11.mov            dword ptr [ebp-8],0Ah           将0Ah(10)放在ebp-8的位置处

12.mov            dword ptr [ebp-14h],14h       将14h(20)放在ebp-14h的位置处    

13.mov            dword ptr [ebp-20h],0           将0放在ebp-14h的位置处

14.mov            eax,dword ptr [ebp-14h]       将ebp-14h的值放在eax中

15.push           eax                                       将eax的值压栈

16.mov            ecx,dword ptr [ebp-8]           将ebp-8的值放在ecx中

17.push           ecx                                       将ecx的值压栈

18.call             00C210E1                            将call指令的吓一条指令压栈(此时进入函数内部)

19.push           ebp                                       将ebp的值压栈

20.mov             ebp,esp                                将esp的值传给edp

21.sub              esp,0CCh                             esp-0CCh(相当于给main函数预留了一段空间)

22.push            ebx                                       将ebx的值压栈

23.push            esi                                        将esi的值压栈

24.push            edi                                        将edi的值压栈

25.lea               edi                                        edi,[ebp+FFFFFF34h](加载有效地址,将 [ ] 中的地址加载到edi中)

                                                                     该地址为,[ebp-0CCh](此地址是第三行的值)

26.mov             ecx,33h                                将33h这个值放入ecx中

27.mov             eax,0CCCCCCCCh             eax中加入0CCCCCCCCh中

28.rep stos      dword ptr es:[edi]                 从第7到9行,从edi地址开始向下ecx个的double字(4字节)全部变成eax中的值

29.mov            dword ptr [ebp-8],0               将0放在ebp-8的位置处

30.mov            eax,dword ptr [ebp+8]          将ebp+8的值放在eax中(10)

31.add             eax,dword ptr [ebp+0Ch]     将ebp+0Ch的值加到eax中(30)

32.mov            eax,dword ptr [ebp-8]           把ebp-8的值放在eax中(30)、

33.pop             edi                                        edi出栈

34.pop             esi                                        esi出栈

35.pop             ebx                                       ebx出栈

36.mov            esp,ebp                                将ebp给esp

37.pop             ebp                                       将弹出的值存入ebp中

38.ret                                                            跳到此时从站栈顶弹出的地址处

39.add             esp,8                                     将esp+8,即esp指向esp+8处,此时相当于将第15和17步的值弹出,空间归还给系统

40.mov            dword ptr [ebp-20h],eax        将eax(30)中的值放到ebp-20h(变量c)中

 

具体回答的问题:

a、局部变量是怎么创建的?

        给函数创建好栈帧空间后在该栈帧空间中给局部变量分配一部分空间。

b、为什么局部变量的值是随机的

        当局部变量为初始化时,相当于使用的值是随机返给的值。

c、函数是怎么传参的,传参顺序是怎样的

        在未调用函数的时候,就将参数push在main()函数的后边,传参的顺序是从右向左push的。

d、形参和实参是什么关系

        形参和实参在值上是相同的,在空间上是相对独立的,所以说形参是实参的临时拷贝     

e、函数调用结束如何返回

        在调用之前就已经将call下一条指令的地址压入栈中,并且将调用的上一个函数的edp的值压入,在返回时依据这两个值来返回。

 注:

a、函数传参是从右向左传的,由31可知形参是实参的一份临时拷贝;

b、寄存器是集成在CPU上的。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值