C语言——函数栈帧的创建和销毁(一)

简介: C语言——函数栈帧的创建和销毁

Hello,好久没有写博客了,前两份都是之前写的,看来最近有点懈怠,最近也得快点找回学习的状态,那今天开始我们新的讲解

在我们刚开始学习C语言的时候,不知道大家有没有困惑,比如我们在使用局部变量的时候,他是怎么创建的呢

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

带着这些疑问,我们开始来介绍函数栈帧的创建和销毁

先给大家普及一个知识,就是我们的寄存器

要了解我们的函数栈帧,最主要的是ebp和esp,这两个寄存器存放的是我们的地址,是来维护函数栈帧的。在我们函数调用的时候,每一次都会创建函数栈帧来维护这个函数。

#include<stdio.h>
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);
  printf("%d\n", c);
  return 0;
}

我们先使用的是main函数,ebp,和esp就是来维护这个函数栈帧的,ebp我们可以认为栈低指针,esp我们可以认为栈顶指针,而我们下一次函数调用的时候是在上面开辟函数栈帧,每一次调用都会开函数调用

其实我们的main函数也是被调用的

下面我们看函数的一个反汇编

因为我们的main函数也是被调用的,所以在调用之前也会开辟一个栈帧,我么来看一下这个图

我们在看下一条指令

因为我们在调用main函数的时候进行压栈,压入一个ebp,ebp中存放的是下面那个ebp的地址,而指令中的mov,就是将esp的值给了ebp,所以其实现在esp和ebp应该指向同一个地址

图是这样的

我们在看下一步

所以我们的esp指向上面的一个位置

那就意味着现在我们给main函数开辟了一个空间,这个空间其实很大的

继续看下面指令

我们不用关心这个值是有什么用,其实也是代表寄存器的,我们先不用关心,只要知道我们push三个值进去。

压栈进去,esp也变了

下一条指令更像是初始化,其实应该是下面的三条指令,首先看我们的lea,其实它的意思就是load effective address,是加载有效地址的意思,就是将后面的【ebp-0E4h】加载到edi里面去,edi是什么,它就是我们刚刚压栈进去的值

啥意思,就是相当于在栈帧中初始化


相关文章
|
6月前
|
存储 C语言
【C语言】——函数栈帧的创建与销毁
【C语言】——函数栈帧的创建与销毁
|
9月前
|
存储 安全 C语言
深度剖析c语言程序 -- 函数栈帧的创建和销毁(纯肝货)-2
深度剖析c语言程序 -- 函数栈帧的创建和销毁(纯肝货)-2
|
9月前
|
存储 编译器 C语言
深度剖析c语言程序 -- 函数栈帧的创建和销毁(纯肝货)-1
深度剖析c语言程序 -- 函数栈帧的创建和销毁(纯肝货)-1
110 0
|
9月前
|
存储 编译器 C语言
C语言:底层剖析——函数栈帧的创建和销毁
C语言:底层剖析——函数栈帧的创建和销毁
|
9月前
|
存储 编译器 程序员
C语言之反汇编查看函数栈帧的创建与销毁(二)
C语言之反汇编查看函数栈帧的创建与销毁(二)
|
9月前
|
存储 编译器 程序员
C语言之反汇编查看函数栈帧的创建与销毁(一)
C语言之反汇编查看函数栈帧的创建与销毁(一)
C语言之反汇编查看函数栈帧的创建与销毁(一)
|
编译器 C语言
函数栈帧的创建和销毁(以C语言代码为例,汇编代码的角度分析)(下)
函数栈帧的创建和销毁(以C语言代码为例,汇编代码的角度分析)
|
1月前
|
存储 编译器 C语言
【C语言程序设计——函数】分数数列求和2(头歌实践教学平台习题)【合集】
函数首部:按照 C 语言语法,函数的定义首部表明这是一个自定义函数,函数名为fun,它接收一个整型参数n,用于指定要求阶乘的那个数,并且函数的返回值类型为float(在实际中如果阶乘结果数值较大,用float可能会有精度损失,也可以考虑使用double等更合适的数据类型,这里以float为例)。例如:// 函数体代码将放在这里函数体内部变量定义:在函数体中,首先需要定义一些变量来辅助完成阶乘的计算。比如需要定义一个变量(通常为float或double类型,这里假设用float。
36 3
|
1月前
|
存储 算法 安全
【C语言程序设计——函数】分数数列求和1(头歌实践教学平台习题)【合集】
if 语句是最基础的形式,当条件为真时执行其内部的语句块;switch 语句则适用于针对一个表达式的多个固定值进行判断,根据表达式的值与各个 case 后的常量值匹配情况,执行相应 case 分支下的语句,直到遇到 break 语句跳出 switch 结构,若没有匹配值则执行 default 分支(可选)。例如,在判断一个数是否大于 10 的场景中,条件表达式为 “num> 10”,这里的 “num” 是程序中的变量,通过比较其值与 10 的大小关系来确定条件的真假。常量的值必须是唯一的,且在同一个。
20 2
|
1月前
|
存储 C语言
【C语言程序设计——函数】递归求斐波那契数列的前n项(头歌实践教学平台习题)【合集】
本关任务是编写递归函数求斐波那契数列的前n项。主要内容包括: 1. **递归的概念**:递归是一种函数直接或间接调用自身的编程技巧,通过“俄罗斯套娃”的方式解决问题。 2. **边界条件的确定**:边界条件是递归停止的条件,确保递归不会无限进行。例如,计算阶乘时,当n为0或1时返回1。 3. **循环控制与跳转语句**:介绍`for`、`while`循环及`break`、`continue`语句的使用方法。 编程要求是在右侧编辑器Begin--End之间补充代码,测试输入分别为3和5,预期输出为斐波那契数列的前几项。通关代码已给出,需确保正确实现递归逻辑并处理好边界条件,以避免栈溢出或结果
65 16

热门文章

最新文章