底层原理——函数栈帧创建于销毁(图文详解)

函数空间创建销毁全过程(详解~) 理解函数创建销毁,探寻c语言函数的内部世界,逻辑严密 阅读详情

目录

前言

一、寄存器

二、演示代码(c语言)

二、汇编逐一分析函数的创建

1.main函数空间的开辟

2.局部变量的创建​编辑

3.Add函数的创建

3.1形参的创建​编辑

3.2Add函数空间开辟

3.3实现函数内功能

三、函数栈帧的销毁


前言

相信大家在初学c语言时都有很多的点不是很清楚,比如为什么函数传参时形参改变不了实参,为什么代码会出现烫烫烫,局部变量是怎么创建的?等等问题,带着这些问题,我们今天来研究研究函数的栈帧创建于销毁。

一、寄存器

寄存器是集成于cpu上的独立存储空间。

我们想要了解函数的栈帧创建于销毁,得先了解一下部分寄存器的名称于功能。

eax,ebx,ecx,edx等是用于存储数据的寄存器

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

当某个函数被调用时,esp和ebp就会来维护这个函数。

二、演示代码(c语言)

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);
    return c;
}

我将对如上代码分析,带你理解函数栈帧

二、汇编逐一分析函数的创建

1.main函数空间的开辟

esp和ebp先维护调用main函数的函数

 

接下来开始调用main函数:

逐一分析这些汇编代码

1.将ebp的值压入栈顶

2.将esp赋给ebp的位置

3.将esp中的值减去0E4h,esp是指针,减去0E4h后得到一个新的地址(栈区中数据是由高地址到低地址开辟空间,所以esp往栈顶移动)

4.将ebx的值压入栈顶

5.将esi的值压入栈顶

6.将edi的值压入栈顶

7.lea(load effective address) 将(ebp-0E4h)的有效地址加载到edi去

8.将9赋给ecx

9.将0CCCCCCCCh赋给eax

10.从(ebp-0E4h)地址处开始的39h的dword(4字节)的所有的值改为0CCCCCCCCh

如下图:

2.局部变量的创建

1.将0Ah赋给(ebp-8)的4个字节处

2.将14h赋给(ebp-14h)的4个字节处

3.将0赋给(ebp-20h)的4个字节处

3.Add函数的创建

3.1形参的创建

1.将(ebp-14h)地址处的值赋给eax

2.栈顶压入eax

3.将(ebp-8)地址处的值赋给ecx

4.栈顶压入ecx

3.2Add函数空间开辟

这条指令是调用Add函数的

在栈顶压入00c2144B的下一条指令00c21450,以便调用完Add函数以后能够继续下一步操作

这接下来的操作和开辟main函数一样,类比即可。

3.3实现函数内功能

1.将(ebp-8)的值改为0

2.将x值 赋给eax

3.将y值与eax相加并赋给eax

4.将eax的值赋给(ebp-8)

5.将(ebp-8)的值赋给eax寄存器(因为ebp-8这块空间随着Add函数栈帧的销毁也会随之还给操作系统,所以需要用eax寄存器来保存z的值,使得返回main函数后能够使用z的值)

三、函数栈帧的销毁

1.弹出edi

2.弹出esi

3.弹出ebx

4.将ebp的值赋给esp

5.弹出ebp

最终回到了最初调用Add的状态。

C生万物 | 反汇编深挖【函数】的创建销毁 从汇编角度深度挖掘函数建立和销毁的全过程,保姆式教学,超详细解说 阅读详情

相关推荐

ubuntu Matlab R2024a 安装破解

秘钥:21471-07182-41807-00726-32378-34241-61866-60308-44209-03650-51035-48216-24734-36781-57695-35731-64525-44540-57877-31100-06573-50736-60034-42697-39512-63953。右键--点击属性--点击权限--访问设置全部设置成读取和写入,执行操作后右上角的锁符号会显示,再将被替换的文件执行。挂载后打开,右键空白处,点击以终端打开,输入:./install回车。

m0_60931383的博客 1万+

深入理解函数创建销毁

底层学习函数创建销毁。全过程图解,附动图演示,生动形象。看完面试官直呼内行!!!

罅隙的博客 3919

【C语言】程序员筑基功法——《函数创建销毁

汇编角度带你走进函数

StackFrame 3609

函数(详细图解)

一、 简单来说是一块由函数运行而临时占用的内存区域,其主要特点有: 一个限定表尾进行删除(出)和插入(入)操作的线性表,其过程类似与压子弹与退子弹。 一个由系统自动分配的内存空间。 用于存储函数内部的局部变量、方法调用、函数传参数值等。 由高地址向低地址生长。 ...

ZHOUZH的博客 2万+

是什么? 利用EBP(指针)寄存器访问内局部变量、参数、函数返回地址等的手段。 为单个过程,一个函数调用分配的那部分称为,一个的底部由EBP指向,作为在该内访问所有内容的基准(所有访问地址都以该EBP为准相对偏移),ESP则在移动着,作为该的顶部。 的作用是什么? 在程序中用于声明局部变量,调用函数。 在函数调用时,将ESP当前的值保存在EBP中,之后以E

janessa_jp的博客 670

【C语言深度解剖】函数创建销毁(超详细·图文版·适合面试/底层原理

本文深入讲解了C语言函数调用过程中创建、维护和销毁机制。通过分析函数调用时ebp/rbp和esp/rsp寄存器的变化,详细展示了参数传递、局部变量存储、返回值处理等关键环节的底层实现原理。文章采用32位环境下的汇编代码和内存示意图,直观呈现了的动态变化过程,包括函数调用时的参数压顺序(从右向左)、返回地址保存、局部变量空间分配以及销毁时的寄存器恢复等核心概念。最后总结了函数的8个关键特性,帮助读者深入理解C语言函数调用的底层逻辑,为解决溢出、指针越界等问题提供理论基础。

2602_95178652的博客 1436

函数创建销毁

当我们在写C语言代码的时候,为了使代码整洁高效,经常会把一个独立的功能抽象为函数,所以C程序是以函数为基本单位的。这也是C语言的特点之一(面向过程那函数是如何调用的?函数的返回值又是如何返回的?函数参数是如何传递的?这些问题都和函数有关系。函数(stack frame)就是函数调用过程中在程序的调用(call stack)中所开辟的空间,这些空间是用来存放函数参数和函数返回值的。临时变量 (包括函数的非静态的局部变量以及编译器自动生产的其他临时变量)

q38491的博客 2648

函数函数桢的创建销毁

前置知识、函数创建销毁的具体过程、要解决的问题及答案

志之所趋,无远弗届,穷山距海,不能限也 3302

函数创建销毁

我们学习语法学习编程逻辑都是基于封装好的知识上来进行学习,知其然而不知其所以然,如果想要更好的掌握理解所学知识,我们对知识应该有一个更深层次理解,了解过基本语法的伙伴应该都有过下面这些疑问,这些问题怎么去理解,这里就需要我们去了解函数创建销毁; 1.局部变量是怎么创建的? 2.为什么局部变量不初始化的值是随机值? 3.函数是怎么传参的?传参的顺序是怎么样的? 4.形参和实参是什么关系? 5.函数调用是怎么做的? 6.函数调用结束后怎么返回的? 如果上面问题你都能了解,在此让我叫

weixin_59406869的博客 2268

深入理解函数:从创建销毁底层逻辑

本文深入解析函数创建销毁机制。函数函数调用时在调用中开辟的空间,用于存储函数参数、返回值、局部变量和上下文信息。遵循"先进后出"原则,由ESP和EBP寄存器维护。文章通过VS2019反汇编代码详细演示了main函数和Add函数创建过程,包括局部变量初始化、参数传递、寄存器保存等关键步骤,并解释了未初始化局部变量出现随机值的原因。最后分析了函数返回时的销毁过程,包括寄存器恢复和指针调整。这些底层机制揭示了函数调用、参数传递、返回值带回来的实现原理

2401_82938105的博客 1962

函数创建销毁】(超详细图解)

函数创建销毁

m0_63635730的博客 3355

探秘函数:从创建销毁底层之旅

函数,是程序运行时调用函数时,在内存(Stack)中为函数分配的一块连续内存区域,用于存储函数的局部变量参数返回地址以及其他函数调用相关的信息,确保函数能够正确执行并返回到调用点继续后续操作。

2301_80807593的博客 1863

[内功修炼]函数创建销毁

我们在写C语言代码的时候,经常会把一个独立的功能封装在一个函数中,因此,C程序是以函数为基本单位的,那函数是如何调用的呢?函数的返回值又是如何带回呢?函数的参数又是如何传递的呢?这些都与函数有关系。函数就是用来函数在调用过程中在程序的调用所开辟的空间,这些空间是用来存放:(1):函数参数和返回值(2):临时变量(包括函数的非静态区的局部变量以及编译器自动产生的其他临时变量)(3):保存上下文信息 (包括在函数调用前后需要保持不变的寄存器)

ABWSO的博客 1655

【C语言】——函数创建销毁

函数创建销毁,逐语句分析

dab112的博客 1365

探秘函数:『 揭开函数创建销毁的神秘面纱 』

详细讲解函数创建销毁的过程。

qq_63320529的博客 1248

深入解析函数创建销毁

函数(Stack Frame)是函数调用时在调用上分配的内存空间,用于管理函数执行过程。主要内容包括函数参数、返回值、局部变量、返回地址和寄存器状态等。理解能帮助解决局部变量生命周期、参数传递机制(从右向左压)、返回值传递(通过寄存器)等核心问题。创建销毁涉及寄存器(esp、ebp)操作和汇编指令(push、pop、call、ret等)。通过VS2019反汇编代码分析,展示了main函数和Add函数创建、参数传递(形参是实参的拷贝)及销毁过程,揭示了函数调用的底层实现机制。

祯的博客 2210

函数创建销毁详解(C语言拓展版)

本文深入讲解了C语言函数创建销毁过程。通过VS2022环境下的汇编代码分析,揭示了函数调用时空间分配的机制:使用ebp和esp寄存器维护函数调用前压入参数和返回地址,调用时开辟新。重点解释了局部变量的创建(在中分配空间)、未初始化变量的随机值来源(0xCCCCCCCC)、函数传参方式(压临时拷贝)、形参与实参的关系等常见问题。文章还展示了main函数如何被其他函数调用、函数返回时如何恢复底层细节,帮助读者理解递归调用导致溢出的原因。这些底层知识对于掌握指针等高级概念具有重

lingran__的博客 2106

函数创建销毁【此一篇,足以让卿彻底扫盲】

在经典的计算机科学中,被定义为一种特殊的容器,用户可以将数据压入中(入,push),也可以将已经压入中的数据弹出(出,pop),但是这个容器必须遵守一条规则:先入的数据后出(First In Last Out, FIFO)。指令1,指令2:mov,push,将b的值给eax,将eax的值压,改变esp的位置,指令3:指令4:mov,push,将a的值给ecx,将exc的值压,改变esp的位置。指令2,3,4:将a,b的值给eax寄存器,完成整数的减法,并将exa的值赋给z;

FSRMWK的博客 1521

基于STM32、HAL库的GZP6816D气压传感器 驱动程序设计

测量范围:0-16kPa(可根据型号不同有变化)工作电压:1.8V-3.6V。高精度:±1% FS。

corlin6688的博客 192

SRIO_4x_DSP2FPGA.zip_C6678_FPGA SRIO_fpga_milebk8_srio fpga

C6678开发板高速串口与FPGA之间的通信配置,应用程序

上一篇: (c语言)static的用法详解
下一篇: 数据在内存中存储方式(上)
墨染萧然
博客等级 码龄4年 472粉丝 57原创
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

墨染萧然

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值