C语言之函数栈帧的创建与销毁讲解(1)

news2024/10/7 19:18:29

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

例如:局部变量是怎么创建的

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

            函数是怎么样传参的   传参的顺序是什么

            形参和实参的关系是什么

            函数调用是怎么做的

            函数掉调用结束后怎么返回的

这篇博客我们来修炼自己的内功,掌握好这篇博客的大部分知识就已经很不错了

我们用到VS2013这个编译器,目的是为了看到更详细的函数封装内容

现在我们开始我们的正题

要想了解函数栈帧,首先我们要了解一下寄存器,寄存器有我们熟悉的eax  ebx  ecx  edx

今天我们重点理解并掌握ebp  esp这两个寄存器,这两个寄存器中存放的是地址,这两个地址是用来维护函数栈帧的

注意:先提醒一下大家,

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

现在我们写一个代码来观察一下

正在调用哪个函数我这个ebp  esp就在维护哪个函数的函数栈帧,比如我F10调试起来进入main函数,这时我的esp ebp就在维护main函数的函数栈帧

其实在我们的VS2013中,main函数也是被其他函数调用的,那么是谁呢???

下面给大家画个图

 

下面我们接着走 

push:压栈

move:移,放值

pop:出栈 

sub:减

先看最开始的几个步骤

push:先在栈顶压一个ebp

move:把esp的值给了ebp(将地址传给ebp)

sub:给esp减去一个0E4h(八进制位数)这个值,减去一个0E4h的值后值变小了(地址变小了),那么此时ebp就指向了栈顶低地址

lea:load effective address(加载有效地址),ebp-0E4h就是再main函数的栈顶,为什么呢,这是因为我们前几个步骤在算的时候,esp在减去了一个0E4h之后就已经到达了栈顶,前面又把esp的值(地址)赋值给了ebp,所以理所当然的到达了栈顶,希望大家能够理解

再将ebx   esi  edi分别压栈压在栈顶

大家可以边调式边看我给大家写的步骤,我如果一边写一边画图会很不方便,大家可以先跟着我的步骤先自己尝试着画一下,我在博客的最后给大家画了完整的图供大家参考

 再看下面几个步骤,这里大家再最后几个步骤理解起来有点困难,我这里用通俗易懂的语句给大家解释一下,这里的eax存放的是0CCCCCCCCh这个值,从edi开始向下的ecx里面放的值全部放成CCCCCCCC这个值,这里再强调一遍word--2个字节,dword--4个字节,希望大家能够理解!!!

最上面是低地址,最下面是高地址

这就是为什么我们再VS编译器上面经常打印处烫烫烫烫,就是因为最开始没有在main函数里面定义变量的时候里面放的都是随机值,当然在不同的编译器上面效果不同,大家感兴趣可以去试试

我们再往下走

 这是我们打开了显示符号名这个按键,方便我们看地址,这里告诉大家如何操作,看下图

这里有5个按钮,根据你的需求操作即可 

mov这个意思我们上面已经讲到了,比如a,将14h(十六进制数也就是20,自己可以计算一下,1*16加上4*16的0次方),将20这个数字放到ebp-8这个地址里面,dword--4个字节,见下面我画的图大家就能理解

 

大家现在想一想我们为什么在main函数内部定义一个变量必须要初始化吗?就是为了避免打印随机值,大家现在可能就豁然开朗,为什么我们一下强调变量要初始化,这也就为什么我们要养成一个良好的写代码的习惯

大家可以跟着我的步骤在VS2013上按住F10调试起来,打开调试里面窗口,然后点击调用堆栈,再点击监视(里面有4个窗口,随机点一个即可),然后打开内存(里面也有4个窗口,随机点一个可),里面能看到你调试起来的的详细内容,没有操作好的可以在评论区写下你的问题,我可以尽力给你解答

再次强调复习一下下面的知识

word--表示两个字节

dword--表示4个字节

 

对于Add函数我们下一篇博客在给大家详细讲解,和前面的main函数大同小异,重在理解,谢谢大家的支持

本章完!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL数据库,从入门到精通:第四篇——MySQL中常用的运算符及其用法

MySQl学习(MySQL数据库,从入门到精通:第四篇——MySQL中常用的运算符及其用法 第四篇_MySQL中常用的运算符及其用法运算符1. 算术运算符1.加法与减法运算符2.乘法与除法运算符3.求模(求余&#…

【Linux】在工作站或服务器上实现多个GUI图形界面同时进行操作,多个用户同时操作互不干扰

一、问题背景 因为我们团队有几个人需要做仿真,一个工作站不够用,经常是一个人操作的时候另一个人就眼巴巴等着。 我在想能不能实现一种方案,能使两个人一起操作仿真软件呢? 这种方案,目前网上比较流行是x11-forwar…

NLP——ELMO;BERT;Transformers

文章目录 ELMOELMO 简介ELMO 优点利用了多层的 hidden 表示ELMO 缺点 BERTBERT V.S. ELMO两种预训练任务Object1: Masked Language ModelObject2: Next sentence prediction 训练细节如何使用 BERTBERT 应用——垃圾邮件分类 Transformerself-attentionMulti-head AttentionTra…

chatgpt赋能python:Python中如何判断奇偶数

Python中如何判断奇偶数 当我们在Python中编写程序时,有时需要判断一个数是奇数还是偶数,因为根据不同的情况,我们需要对不同的数值进行不同的处理。那么在Python中,该如何判断一个数是奇数还是偶数呢? 判断奇偶数的…

【JavaEE进阶】mybatis

目录: 一、Mybatis是什么 三个映射关系如下图: 二、mybatis的使用(前置工作简单案例) 第一步:导入MAVEN依赖 第二步: 在spring项目当中新建数据源 第三步:新建一个实体类,是和…

Shell编程规范与变量使用

目录 一、Shell编程概述 1.Shell脚本的概念 2.Shell脚本的应用场景 3.Shell的作用 4.Linux系统中支持的shell 二、Shell编程规范 1.编写Shell脚本规范步骤 2.Shell脚本执行方法 (1)以绝对路径执行(需要赋予脚本文件执行权限&#xf…

stable diffusion webui 文生图(txt2img)api接口调用(使用C#)

唠嗑 本次将跟读者讲一下如何通过C#请求sd webui api 【txt2img】接口,如果读者觉得文章有用,请给【点个赞】吧,有问题可以评论区提问。 实战 1.配置api启用参数 启动webui时,需加上【–api】 命令以保证api接口可以被调用。如…

Shell脚本文本三剑客之awk编辑器

目录 一、sed编辑器简介 二、sed工作流程 三、sed命令 四、sed命令的使用 1.sed打印文件内容(p) (1)打印文件所有行 (2)打印文件指定行 2.sed增加、插入、替换行(a、i、c) …

Shell脚本之正则表达式详解

目录 一、正则表达式简介 二、正则表达式的组成 三、正则表达式分类 四、正则表达式字符用法 1.基础正则表达式常见元字符(支持grep、egrep、sed、awk) 2. 扩展正则表达式元字符(支持:egrep、grep -E、awk、sed -r&#xff…

C语言之数据在内存中的存储(2)

本章重点:浮点数在内存中的存储 浮点数:数学中的小数 eg.123.45 12.345*10^1 1.2345*10^2 1E10:1.0*10^10 整型家族的类型,表示范围:limits.h 浮点数:float.h 大家可以猜测一下打印的这四个数字…

Unity中动画系统的性能优化

降低骨骼数,减少面片数。 方法: 1.勾选Optimize Game Objects,以剔除骨骼节点对应的Transform节点 2.开启多线程渲染选项 主要影响的函数调用开销,可以在profiler中查看: Animators.Update MeshSkinning.Update C…

【TCP/IP】多进程服务器的实现(进阶) - 信号处理及signal、sigaction函数

目录 信号 signal函数 sigaction函数 尝试用信号来处理僵尸进程 我们在之前学习了如何处理“僵尸进程”,但也会有疑问:调用wait和waitpid函数时我们关注的始终是在子进程上,那么父进程上的管控(对于子进程)该如何实…

STM32——05-按键、时钟控制、中断复位 点亮LED灯

如何点亮一颗LED灯 编程实现点灯 常用的 GPIO HAL 库函数: void HAL_GPIO_Init ( GPIO_TypeDef * GPIOx , GPIO_InitTypeDef * GPIO_Init ); void HAL_GPIO_WritePin ( GPIO_TypeDef * GPIOx , uint16_t GPIO_Pin , GPIO_PinState PinState ); void HAL_GPIO_Togg…

chatgpt赋能python:Python如何创建新项目

Python如何创建新项目 Python已经成为了全球最受欢迎的编程语言之一。如果您是一个有经验的Python工程师,您可能已经知道如何在命令行上创建新项目。但是,如果您是一个新手或初学者,您可能需要一些指导来开始创建新的项目。在本篇文章中&…

Vue中如何进行样式绑定?

Vue中如何进行样式绑定? 在Vue中,我们可以很方便地进行样式绑定。样式绑定是将CSS样式与Vue组件中的数据进行关联的一种技术。通过样式绑定,我们可以根据组件的状态动态地修改其外观。本文将介绍Vue中的样式绑定,包括类绑定、内联…

chatgpt赋能python:Python如何进行升序排列?

Python如何进行升序排列? Python是一门广泛应用于Web开发、数据科学、人工智能、机器学习等领域的编程语言。在这个快速发展的世界中,如何高效地排序数据是非常重要的。本文将介绍Python中如何进行升序排序。 基本排序方法 Python提供了一个内置函数s…

Vue 中的列表渲染

Vue 中的列表渲染 在 Vue 中,列表渲染是非常常见的操作。它允许我们将一个数组中的数据渲染为一个列表,从而实现数据的展示和交互。在本文中,我们将探讨 Vue 中的列表渲染的基本原理和用法,并给出一些实例代码来帮助读者更好地理…

【模块三:职业成长】38|能力维度三:如何提升解决跨领域冲突的能力?

你好,我是郭东白。今天我们来讨论架构师核心能力的第三个层次——解决跨领域冲突。 上节课我们讲了从程序员到兼职架构师的跨越,也就是如何搭建解决横向问题的能力。 不过,在兼职架构师这个角色中,架构能力是一个加分项&#xff…

chatgpt赋能python:如何使用Python升序排列一个列表?

如何使用Python升序排列一个列表? 在Python编程中,我们经常需要对列表进行排序。列表排序是一种常见的操作,可以帮助我们对数据进行分析和管理。在这篇文章中,我们将学习如何使用Python对一个列表进行升序排列。 什么是升序排列…

时间同步/集群时间同步/在线/离线

目录 一、能够连接外网 二、集群不能连接外网--同步其它服务器时间 一、能够连接外网 1.介绍ntp时间协议 NTP(Network Time Protocol)网络时间协议,是用来使计算机时间同步的一种协议,它可以使计算机对其服务器或时钟源做同步…