【C语言初阶】函数栈帧的创建和销毁-创新互联-成都创新互联网站建设

关于创新互联

多方位宣传企业产品与服务 突出企业形象

公司简介 公司的服务 荣誉资质 新闻动态 联系我们

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

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

创新互联是一家专业提供利津企业网站建设,专注与成都网站建设、网站建设、H5高端网站建设、小程序制作等业务。10年已为利津众多企业、政府机构等服务。创新互联专业的建站公司优惠进行中。

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

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

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

mainCRTStartup   --->  __tmainCRTStartup   --->  main

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

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

#includeint 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上的。

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


分享标题:【C语言初阶】函数栈帧的创建和销毁-创新互联
本文URL:http://kswsj.cn/article/dogdhc.html

其他资讯