【C语言】函数栈帧---函数的创建于销毁过程剖析(一览无遗)

目录

 前言:

1.铺垫

寄存器

main函数被谁调用

2.正题

结论: 


 前言:

  • 学习这么久以来,可能有很多疑问:
  • 局部变量怎么创建的?
  • 为什么局部变量的值是随机的?
  • 函数是怎么传参的?传参的顺序是怎么样的?
  • 形参和实参是什么样的关系?
  • 函数调用是怎么做的?
  • 函数调用结束后是怎么返回的?
  • 那么本篇博文就来一一讲解一下。
  • 环境:vs2021,大家也可以使用更低版本的编译器更容易观察出现象。(推荐vc6.0)在不同的编译器下面,函数调用的过程中栈帧的创建是稍有差异的,大体逻辑是一样的具体差异的细节取决于编译器的实现。(越新的编译器封装的就越复杂,不容易抽离出函数栈帧这个过程)

1.铺垫

寄存器

百度百科链接

寄存器中有eax/ebx/ecx/ edx    /ebp/esp

重点是esp/ebp两个寄存器中存放的是地址,这两个地址是用来维护函数栈帧的。

一般吧ebp叫做栈底指针,把esp叫做栈顶指针,栈区的使用习惯是先使用高地址再使用低地址。我们今天测试环境中是rbp,rsp

每一个函数调用都要在栈区上创建或者开辟一块空间。

main函数被谁调用

我们调试调用堆栈

不会调试的可以先看我的这篇文章:vs2021环境调试详细

调用关系

那接下来我们就来看看具体的过程剖析

2.正题

F10运行调试起来,右键来到反汇编,看我们的反汇编代码

刚进入,我们的rbp和rsp在为我们的调用main函数的函数维护栈帧,进入main函数过后

先压入了一个rbp和一个rdi

再讲rsp减148h(这是一个16进制数字)

接着往下:

lea的意思是:load effective address 就是1加载一个地址造rbp中

那么现在的rbp和rsp就维护了main函数维护的这块空间。

main函数的空间开辟好了过后,开始执行main函数中的代码:

往下执行:

edx  存储20

ecx 存储10

然后call调用add函数

先将edx的值放到rsp+10的位置

将ecx的值放到rsp+8的位置

压入rbp和rdi

 return后,将rbp+E8h给rsp,相当于销毁了add的栈帧

将rbp和rid出栈(这里由于我重新启动了一次所以数据不一样,不过还是可以看到rbp和rsp之间相差20.回到了起点,原先的空间被释放了)

结论: 

那到这里我们就已经可以回答了

局部变量是如何创建的:

调用函数的时候在栈上开辟空间过后,在这块空间里给变量分配空间。

为什么局部变量不初始化是随机值?

因为随机值是随机写入的,创建好空间后就会将这块空间的值变为随机值。初始化就将随机值覆盖

函数如何传参:

还没有调用函数的时候,就将这参数的值通过寄存器(ebx,ecx)push到了栈顶,通过指针偏移的方式找到形参。

形参和实参的关系:

形参是在压栈时独立开辟的空间(ebx,ecx),值相同,空间二者各自独立。

函数是如何返回的

调用函数之前,都会调用call指令,会将调用call指令的后一条指令的地址先压入栈,然后将函数调用的上一个函数的rdp也压入栈,函数调用结束返回pop(弹出edp)就得到我们上一个函数的函数栈帧的维护地址,就回到了原始栈帧空间,又有下一条指令的地址,就可以继续运行。返回值通过寄存器eax带回。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/544739.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024最新手赚手机软件APP下载排行网站源码及应用商店源码

这是一款简洁蓝色的手机软件下载应用排行、平台和最新发布网站,采用响应式织梦模板。主要包括主页、APP列表页、APP详情介绍页、新闻资讯列表、新闻详情页、关于我们等模块页面。 源码下载:https://download.csdn.net/download/m0_66047725/88898956 更…

java serlvet 高校学生画像平台系统Myeclipse开发mysql数据库web结构java编程计算机网页项目echarts图形展现

一、源码特点 java serlvet 高校学生画像平台系统是一套完善的java web信息管理系统 系统采用serlvetdaobean 模式开发本系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为TOMCA…

yocto 集成ros2(基于raspberrypi 4B)

yocto 集成ros2 上一小节已经使用yocto编译出了raspberrypi 4B的image。并且成功刷机并且启动登陆: 链接: yocto 编译raspberrypi 4B并启动 本节我们将ros2机器人操作系统移植到我们的yocto系统里面。 1. 下载ros layer 上小节我们编译的yocto image是基于kirkst…

HarmonyOS(二十)——管理应用拥有的状态之LocalStorage(页面级UI状态存储)

LocalStorage是页面级的UI状态存储,通过Entry装饰器接收的参数可以在页面内共享同一个LocalStorage实例。LocalStorage也可以在UIAbility实例内,在页面间共享状态。 本文仅介绍LocalStorage使用场景和相关的装饰器:LocalStorageProp和LocalS…

智慧城市革命,物联网技术如何改变城市治理与生活方式

随着科技的不断进步,智慧城市已经成为现代城市发展的重要方向之一。物联网技术作为智慧城市的重要支撑,正深刻改变着城市的治理模式和居民的生活方式。本文将探讨智慧城市革命,以及物联网技术如何改变城市治理与生活方式,同时介绍…

贪心算法(两个实例)

例一:调度问题 问题:由n项任务,每项任务的加工时间已知,从零时刻开始陆续加入一台机器上去加工,每个任务完成的时间是从0时刻到任务加工截至的时间。 求总完成时间(所有任务完成时间最短计划方案&#xf…

游戏服务端配置“热更”及“秒启动”终极方案(golang/ygluu/卢益贵)

游戏服务端配置“热更”及“秒启动”终极方案(golang/ygluu/卢益贵) 关键词:游戏微服务架构、游戏服务端热更、模块化解耦、golang 一、前言 众所周知,游戏服务端配置信息热更有几大问题(非lua架构)&…

【Machine Learning】Suitable Learning Rate in Machine Learning

一、The cases of different learning rates: In the gradient descent algorithm model: is the learning rate of the demand, how to determine the learning rate, and what impact does it have if it is too large or too small? We will analyze it through the follow…

wsl ubuntu 安装的正确方式

目录 wsl ubuntu 安装的正确方式: 将wsl2设置为默认版本: 1、打开powershell 2、设置wsl的版本为2 ​编辑 3、更新wsl程序 4、强制关闭子系统 5、查看wsl支持的列表 6、安装指定版本的系统 wsl ubuntu 安装的正确方式: 此时&#xff0c…

NCV4275CDT50RKG稳压器芯片中文资料规格书PDF数据手册引脚图图片价格功能

产品概述: NCV4275C 是一款低漏稳压器,可用于严酷汽车环境。它包括了较宽的运行温度范围和输出电压范围。输出调节为 5.0 V 或 3.3 V,额定输出电流为 450 mA。它还提供过电流保护、超温保护和可编程微处理器重置等多种功能。NCV4275C 采用 D…

【LeetCode热题100】148. 排序链表(链表)

一.题目要求 给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。 二.题目难度 中等 三.输入样例 示例 1: 输入:head [4,2,1,3] 输出:[1,2,3,4] 示例 2: 输入:head [-1,5,3,4,0] 输…

【ArcGISPro】道路数据下载并使用

下载 下载链接: Geofabrik 下载服务器 这些数据通常 每天更新。 下载结果 arcmap用户下载工具 10.2:http://www.arcgis.com/home/item.html?id=16970017f81349548d0a9eead0ebba39 10.3: