什么是C++的堆栈指引
创始人
2024-12-25 14:23:38
0次

  我们经常会讨论这样的问题:什么时候数据存储在堆栈(Stack)中,什么时候数据存储在堆(Heap)中。我们知道,局部变量是存储在堆栈中的;debug时,查看堆栈可以知道函数的调用顺序;函数调用时传递参数,事实上是把参数压入堆栈,听起来,堆栈象一个大杂烩。那么,堆栈(Stack)到底是如何工作的呢?本文将详解C/C++堆栈的工作机制。阅读时请注意以下几点:

  1)本文讨论的编译环境是VisualC/C++,由于高级语言的堆栈工作机制大致相同,因此对其他编译环境或高级语言如C#也有意义。

  2)本文讨论的堆栈,是指程序为每个线程分配的默认堆栈,用以支持程序的运行,而不是指程序员为了实现算法而自己定义的堆栈。

  3)本文讨论的平台为intelx86。

  4)本文的主要部分将尽量避免涉及到汇编的知识,在本文最后可选章节,给出前面章节的反编译代码和注释。

  5)结构化异常处理也是通过堆栈来实现的(当你使用try…catch语句时,使用的就是c++对windows结构化异常处理的扩展),但是关于结构化异常处理的主题太复杂了,本文将不会涉及到。

从一些基本的知识和概念开始

  1)程序的堆栈是由处理器直接支持的。在intelx86的系统中,堆栈在内存中是从高地址向低地址扩展(这和自定义的堆栈从低地址向高地址扩展不同),因此,栈顶地址是不断减小的,越后入栈的数据,所处的地址也就越低。

  2)在32位系统中,堆栈每个数据单元的大小为4字节。小于等于4字节的数据,比如字节、字、双字和布尔型,在堆栈中都是占4个字节的;大于4字节的数据在堆栈中占4字节整数倍的空间。

  3)和堆栈的操作相关的两个寄存器是EBP寄存器和ESP寄存器的,本文中,你只需要把EBP和ESP理解成2个指针就可以了。ESP寄存器总是指向堆栈的栈顶,执行PUSH命令向堆栈压入数据时,ESP减4,然后把数据拷贝到ESP指向的地址;执行POP命令时,首先把ESP指向的数据拷贝到内存地址/寄存器中,然后ESP加4。EBP寄存器是用于访问堆栈中的数据的,它指向堆栈中间的某个位置(具体位置后文会具体讲解),函数的参数地址比EBP的值高,而函数的局部变量地址比EBP的值低,因此参数或局部变量总是通过EBP加减一定的偏移地址来访问的,比如,要访问函数的第一个参数为EBP+8。

  4)堆栈中到底存储了什么数据?包括了:函数的参数,函数的局部变量,寄存器的值(用以恢复寄存器),函数的返回地址以及用于结构化异常处理的数据(当函数中有try…catch语句时才有,本文不讨论)。这些数据是按照一定的顺序组织在一起的,我们称之为一个堆栈帧(StackFrame)。一个堆栈帧对应一次函数的调用。在函数开始时,对应的堆栈帧已经完整地建立了(所有的局部变量在函数帧建立时就已经分配好空间了,而不是随着函数的执行而不断创建和销毁的);在函数退出时,整个函数帧将被销毁。

  5)在文中,我们把函数的调用者称为caller(调用者),被调用的函数称为callee(被调用者)。之所以引入这个概念,是因为一个函数帧的建立和清理,有些工作是由Caller完成的,有些则是由Callee完成的。

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...