文章目录

  • 前言
    • 一、 寄存器的概念
    • 二、 通用寄存器的结构
    • 三、 指针寄存器和变址寄存器
    • 四、 EBP和ESP
    • 五、总结

前言

在前期的学习过程中,我们可能会有很多的困惑:

1️⃣ 局部变量是怎么创建的?

2️⃣ 为什么未初始化的局部变量的值是随机值?

3️⃣ 函数是如何传参的?以及传参的顺序是怎样的?

4️⃣ 形参和实参是什么关系?

5️⃣ 函数调用是怎么做的?

6️⃣ 函数调用结束后是怎么返回的?

⚠ 这里使用的环境是 Visual Studio 2013 ,提示不要使用太过高级的编译器,因为越高级的编译器越不容易观察。同时这里需要注意的是在不同的编译器下,函数调用过程中栈帧的创建是略有差异的,具体细节取决于编译器。

一、 寄存器的概念

寄存器的功能是存储二进制代码,它是由具有存储功能的触发器组合起来构成的。一个触发器可以存储1位二进制代码,故存放n位二进制代码的寄存器,需用n个触发器来构成。
按照功能的不同,可将寄存器分为基本寄存器和移位寄存器两大类。基本寄存器只能并行送入数据,也只能并行输出。移位寄存器中的数据可以在移位脉冲作用下依次逐位右移或左移,数据既可以并行输入、并行输出,也可以串行输入、串行输出,还可以并行输入、串行输出,或串行输入、并行输出,十分灵活,用途也很广。

二、 通用寄存器的结构

通用寄存器组包括AX、BX、CX、DX4个16位寄存器,用以存放16位数据或地址。也可用作8位寄存器。用作8位寄存器时分别记为AH、AL、BH、BL、CH、CL、DH、DL,只能存放8位数据,不能存放地址

1️⃣ AX(AH、AL):累加器。有些指令约定以AX(或AL)为源或目的寄存器。输入/输出指令必须通过AX或AL实现。

2️⃣ BX(BH、BL):基址寄存器。BX可用作间接寻址的地址寄存器和基地址寄存器,BH、BL可用作8位通用数据寄存器。

3️⃣ CX(CH、CL):计数寄存器。CX在循环和串操作中充当计数器,指令执行后CX内容自动修改,因此称为计数寄存器。

4️⃣ DX(DH、DL):数据寄存器。除用作通用寄存器外,在I/O指令中可用作端口地址寄存器,乘除指令中用作辅助累加器。

三、 指针寄存器和变址寄存器

1️⃣ BP( Base Pointer Register):基址指针寄存器。

2️⃣ SP( Stack Pointer Register):堆栈指针寄存器。

3️⃣ SI( Source Index Register):源变址寄存器。

4️⃣ DI( Destination Index Register):目的变址寄存器。

这组寄存器存放的内容是某一段内地址偏移量,用来形成操作数地址,主要在堆栈操作和变址运算中使用。BP和SP寄存器称为指针寄存器,与SS联用,为访问现行堆栈段提供方便。通常BP寄存器在间接寻址中使用,操作数在堆栈段中,由SS段寄存器与BP组合形成操作数地址即BP中存放现行堆栈段中一个数据区的“基址”的偏移量,所以称BP寄存器为基址指针。
SP寄存器在堆栈操作中使用,PUSH和POP指令是从SP寄存器得到现行堆栈段的段内地址偏移量,所以称SP寄存器为堆栈指针,SP始终指向栈顶。
寄存器SI和DI称为变址寄存器,通常与DS一起使用,为访问现行数据段提供段内地址偏移量。在串指令中,其中源操作数的偏移量存放在SⅠ中,目的操作数的偏移量存放在DI中,SI和DI的作用不能互换,否则传送地址相反。在串指令中,SI、DI均为隐含寻址,此时,SI和DS联用,Dl和ES联用。

四、 EBP和ESP

这是单独把 EBP 和 ESP单独拎出来,不用说它两肯定和我们的主题脱不了干系 —— 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;
}

不知道大家有没有好奇 Add 被 main 函数调用,而 main 函数被谁调用呢 ❔❓

1、调试代码后,打开调用堆栈

2、这时看到调用堆栈这个窗口 main 函数被调用了,问题也就出现了 —— main函数被谁调用了

3、当程序继续走时,它跳到了crtexe.c文件中,这时再看堆栈窗口发现 main 函数被 __tmainCRTStartup() 调用

4、而 __tmainCRTStartup() 又被 mainCRTStartup() 调用


解决完疑问后,这里就细看代码的底层是如何执行的 ❔❓

这里观察C语言代码所对应的汇编代码 —— 调试代码后,右击鼠标转到反汇编

1️⃣ 先为调用 main 函数的这个函数 __tmainCRTStartup 开辟函数栈帧,并用 esp 和 ebp 维护

2️⃣ 为 main 函数开辟函数栈帧

2.1、push ebp

压栈 ebp,esp 指向的位置也随之改变 (地址减小)

▶ 压栈前

▶ 压栈后

内功修炼《函数栈帧的创建和销毁》建议收藏相关推荐

  1. 程序员内功修炼——函数栈帧的创建与销毁

    一.什么是函数的栈帧 c语言是由函数构成的,那么函数是如何进行传参的?如何调用的?如何返回值的?这些问题与函数的栈帧有关. 函数栈帧:就是函数调用过程中程序的调用栈所开辟的空间,这些空间用来存放: 1 ...

  2. 函数调用过程详解:函数栈帧的创建与销毁

    前言:我们在学习C语言的过程中,可以会产生很多疑问,比如: 局部变量是怎么创建的 为什么局部变量的值不做初始化就是随机值 函数是怎么传参的?传参的顺序是怎么样的? 形参和实参是什么关系? 函数调用是怎 ...

  3. (动图详解)汇编视角观察函数栈帧的创建和销毁

    目录 ​1.阅读本文的价值 ​2.函数栈帧及栈的概念 ​3.部分寄存器及汇编指令 ​4.main函数的调用 5.main函数的栈帧创建 ​6.变量的栈帧创建 ​6.函数传参 ​7.函数内部运算及销毁 ...

  4. 函数栈帧的创建与销毁

    目录 前言 一.预备知识 1.内存区域的划分和分配 2.栈帧简介 3.寄存器简介 二.函数栈帧介绍 1.源代码 2.如何查看汇编代码 3.函数栈帧的创建与销毁(重点) 三.小彩蛋 总结 前言 最近在学 ...

  5. 程序员内功心法之函数栈帧的创建和销毁

    目录 1.本节目标 2.相关寄存器 3.相关汇编指令 4.什么是函数栈帧 5.什么是调用堆栈 6.函数栈帧的创建和销毁 (1).main函数栈帧的创建与初始化 (2).main函数的核心代码 (3). ...

  6. 【C语言】程序员筑基功法——《函数栈帧的创建与销毁》

    <函数栈帧的创建与销毁> 文章目录 1. 前言 2. 问题引入 3. 前提准备 3.1 寄存器 3.2 汇编指令 4. 函数栈帧的维护 5. 如何调用堆栈 6. 函数栈帧的创建和销毁 6. ...

  7. C语言内功修炼之函数栈帧的创建与销毁(举例加图解)

    大家可能会函数栈帧不了解,可能都没有听过这个,不用着急,在理解函数栈帧之前,我们先来了解一下程序对内存使用的分区大概情况:  区域 作用 栈区(stack) 由编译器自动分配和释放,存放函数的参数值, ...

  8. 函数栈帧的创建和销毁图解

    目录 一.问题: 二.寄存器 栈区 1.寄存器有哪些?有什么作用? 2.编译环境 3.栈区的使用习惯: 4.main函数也是被其他函数调用的 5.汇编代码 三.为main函数创建栈帧 1.main函数 ...

  9. 一文带你深入了解函数栈帧的创建和销毁

    作者介绍:友友们好我是沐曦希,可以叫我小沐

最新文章

  1. 【Python】函数图像绘制:二维图像、三维图像、散点图、心形图
  2. 北京大学纳家勇治研究组在《美国国家科学院院刊》发文阐明时序记忆的神经机制
  3. linux的运维管理UNIT3
  4. 金碧辉煌!皇城定制5月22日正式对外运营开业!
  5. 服务器内存技术知识充电
  6. mysql字段数值累加_mysql字段值(字符串)累加 | 学步园
  7. np读取csv文件_pandas.read_csv函数参数详解
  8. 搜索Maven依赖资源_搜索Maven工件_搜索Maven构件_搜索依赖_搜索构件_搜索工件
  9. VoLTE技术中的会话持续性-eSRVCC
  10. Linux debian live USB,用 Live Magic 制作 Debian Live 光盘
  11. 那些小城里的分析大师们为什么发不了财?
  12. 基于SSM的大学拍卖网站(含文档)
  13. Python爬虫QQ空间
  14. Linux下zip文件解压乱码
  15. This request has been blocked; the content must be served over HTTPS.
  16. 关于“八音盒自定义弹奏”的一些想法
  17. 讲座记录——科技论文写作及科研方法
  18. Java Swing制作古老的打砖块游戏
  19. U盘图标不显示(转)
  20. 一个很好的JAVASCRIPT例子[转载]

热门文章

  1. cs1.5服务器指定ip,求上海地区cs1.5服务器IP
  2. 智慧书-永恒的处世经典格言:1-40
  3. Java6-7章复习
  4. UG数控编程:草图之视图方向着色方式和草图的基准设置
  5. 踏遍青山情未老 —— 九山顶重游记(五)
  6. EEA算法的Matlab实现
  7. html5画分形图形,HTML5/Canvas 可在线调整的朱丽叶分形图
  8. 推荐一个在线测试服务器延迟和丢包的工具 Ping.pe
  9. android连接酒店wifi,Android 在APP内、应用内 连接WiFi
  10. Excel加载项(VS2019、C#)