栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

目录

前言

一、寄存器

二、演示代码(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的状态。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/917066.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号