拓冰建站拓冰建站
首页 / 资讯中心 / 正文

嵌入式学习历程-堆栈分析(裸机篇)

写在前面的话博主只是一个求职中的应届毕业生工作经历尚浅如有问题还请各位大佬不吝赐教指出我的错误十分感谢‍‍‍同时图中出现的视频和截图来自youtube上的core dump首先大家先熟悉一个黑话大家平时说的“堆栈”在百分之九十九的情况下指的是栈而不是堆和栈。栈堆栈1栈有栈顶和栈底之分我们在数据结构的时候都学习过栈是先进后出由高地址向低地址增长。对于绝大部分的ARM/X86而言这句话都是对的所以我们可理解为栈底固定指的就是高地址这个起始地址待我们在函数中定义变量计算等操作的时候就会进行压栈/入栈所以栈顶就开始往低地址增长了。这也是为什么c的编译器需要我们明确类型确定类型的字节所占大小每一个栈帧才能明确其大小也就是栈顶移动的距离。出栈发生在函数调用结束的时候当前栈帧函数所用的栈空间中所有的变量都会出栈意味着生命周期结束static这类关键字修饰的变量放置于.data或者.bss中不在栈内所以不会消失这也是为什么我们说这些关键字改变了它的生命周期同时也让我们明白为什么传一个值到我们自定义的函数里面操作之后离开函数变量修改不生效因为本质上就是在新函数的栈中用一个新的变量来接收这个值操作都是对这个新变量进行操作一旦函数结束这些变量都出栈了自然没法修改想要在函数内部修改外部变量就只能用指针栈顶回退其所有的变量大小的距离就回到了一开始调用函数的地方继续执行。在函数调用结束后有两种情况有无返回值1.有返回值你就必须用一个同类型的变量来接收其返回值就相当于在函数调用的那个地方留了返回值大小的空间后续的栈都是被调用函数的内容return就是最后栈顶回退到你一开始的留的空间写上对应返回值。2.没有返回值那就不需要由变量接收不需要留这个空间直接回退整个被调用栈帧的距离接上原函数的调用处继续执行。所以为什么栈都这么快呢原因就在于它的紧凑和确定性每次函数的调用和退出都有着明确的移动距离不需要花时间去寻找位置或者释放空间直接上下sp移动即可时间复杂度为O(1)。堆堆栈的本质区别就在于此栈只能后进先出有严格的顺序可以保持紧凑无碎片而堆可任意释放任意位置数据导致碎片不可避免。每次写入都需要去寻找足够大的内存这里再加上一些算法在效率和碎片化上面做取舍时间复杂度没法预测擦除也需要去查找又是一笔开销自然速度是远远比不上栈。碎片化简单理解就是总内存空闲空间是足够的但是由于他们之间被有数据的内容隔开了没法连到一起组成一个足够大的空间来存放我的数据。如图所示总空间够但是C没地方放。这东西实际上在大部分的裸机中都是不会去使用的可能这就是为什么提到堆栈大家想到的都是栈而不是堆使用一般就是malloc申请但是对于裸机而言没有比较完善的内存管理malloc确实具备该功能但是对于mcu而言不算是太适用一般都是设计内存池进行管理那频繁使用malloc申请造成的碎片就无法管理这会导致很严重内存浪费和响应延迟。所以对于堆我们的启动文件中默认的设定都是很小的基本不会用到大容量的内存需求放在静态全局数组即可一两个标志位放在函数内部的局部静态变量也够用了尽量避免对堆的使用。栈溢出对于整个栈区而言有一个固定的大小这是一开始就设定好的空间范围所有的函数运行的栈都在其中所以说程序运行的时候栈是动态变化的随着函数调用不断变化但是有一个最大值的限定超过了就会发生栈溢出。老师和工作的师傅们或多或少都有提到过为什么我们不要在单片机这种资源受限的机器中写递归因为递归本质上就是函数一层层的自我调用就会导致栈原来越深一个不小心就超了。但是超了不代表就有事。图中是启动文件默认的栈大小对于c8t6而言有20KB的ramram中主要包含堆栈静态存储区.bss,.data,.rodata他们基本位于最低地址之后是堆而栈我们知道位于高地址而这里默认的栈才1KB他们之间很多的空间都是没有分配的属于空闲区栈溢出的到了空闲区是无感的程序没有任何问题但是如果用超到了低地址那边的数据就会发生异常了这个时候问题才会暴露。另外一种情况叫踩内存对于rtos而言由于有多个栈互相之间如果使用不当就会发生踩踏裸机只有一个这种情况一般不会发生。小结总体来看栈虽然速度远远快过于堆但是因为它严格的管理导致我们的自由度受限你不可能在不移除当前栈顶的情况下去移除其下方的数据不然就会导致栈的结构受到损害。而且栈用起来一旦过深或者静态数据区存放消息过多都会导致栈溢出对于系统而言就是毁灭性的打击基本没有补救机会。堆虽然慢但是极其灵活数据可以随意进出没有什么顺序和限制而且堆内存每次使用都是靠malloc申请内存不足的话是不会让你去用的安全性上有足够的保障。浅浅挖个坑对于rtos而言堆与栈的情况又会发生一些奇妙的变化这个会在下一个的RTOS篇中指出感谢各位看到这里本文部分插图截取自YouTube 频道 Core Dump视频中对于堆栈的分析版权归原作者所有仅用于学习交流侵删。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门