首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >函数栈帧的创建和销毁

函数栈帧的创建和销毁

作者头像
waves浪游
发布2024-01-22 17:45:58
发布2024-01-22 17:45:58
6760
举报
文章被收录于专栏:C语言讲解C语言讲解

在前期的学习中,我们可能会有很多困惑:

  • 局部变量是怎么创建的?
  • 为什么局部变量的值是随机值?
  • 函数是怎么传参的?传参的顺序是怎样的?
  • 形参和实参是什么关系?
  • 函数调用是怎么做的?
  • 函数调用结束后是怎么返回的?

那么通过学习函数栈帧的创建和销毁,以上困惑就会迎刃而解。


注: 本次讲解使用的是vs2013,不要使用太高级的编译器,越高级的编译器,越不容易学习和观察;同时,在不同的编译器下,函数调用过程中栈帧的创建是略有差异的,具体细节取决于编译器的实现。


为了讲清楚函数栈帧,我们需要先做一些铺垫:

寄存器: eax ebx ecx edx ebp esp

ebp、esp这2个寄存器中存放的是地址,这2个地址是用来维护函数栈帧的

每一个函数调用,都要在栈区创建一个空间


接下来,就正式开始介绍函数栈帧的创建和销毁



  1. push ebp

  1. mov ebp,esp

  1. sub esp,0E4h

  1. push ebx push esi push edi

  1. lea edi,[ebp+FFFFFF1Ch] (显示符号名后可以看到就是[ebp-0E4h]) mov ecx,39h mov eax,0CCCCCCCCh rep stos dword ptr es: [edi]

把从edi这个位置开始,向下的39h个dword(double word;一个word是两个字节)的数据,全部改成CCCCCCCC


  1. mov dword ptr [ebp-8],0Ah mov dword ptr [ebp-14h],14h mov dword ptr [ebp-20h],0


  1. mov eax,dword ptr [ebp-14h] push eax mov ecx,dword ptr [ebp-8] push ecx

  1. call 00C210E1

  1. push ebp mov ebp,esp sub esp,0CCh push ebx push esi push edi lea edi,[ebp+FFFFFF34h] mov ecx,33h mov eax,0CCCCCCCCh rep stos dword ptr es:[edi]

  1. mov dword ptr [ebp-8],0

  1. mov eax,dword ptr [ebp+8] add eax,dword ptr [ebp+0Ch] mov dword ptr [ebp-8],eax

  1. mov eax,dword ptr [ebp-8]

把30放到eax这个寄存器里面


  1. pop edi pop esi pop ebx

  1. mov esp,ebp pop ebp

  1. ret

  1. add esp,8

  1. mov dword ptr [ebp-20h],eax

main函数的销毁和Add函数的销毁类似,就不再进行演示了。

总结:

  • 局部变量在函数的栈帧里被分配了一些空间进行创建
  • 局部变量不初始化的时候是随机值(比如上述过程中不初始化之前是cccccccc)
  • 函数在调用之前就把参数从右向左进行压栈;真正进入函数后通过指针的偏移量找到形参
  • 形参是实参的一份临时拷贝,改变形参不会影响实参
  • 通过寄存器把返回值带回来
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-10-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档