从地址和存储器角度重新认识微控制器,分析堆栈 分析代码

📅 2026/6/30 23:06:48
从地址和存储器角度重新认识微控制器,分析堆栈 分析代码
2.STM32 堆栈大小及位置针对stm32内存分配、内存溢出等问题分析计算机的bss段data段、text 段、堆(heap)和栈(stack)的了解参考资料https://blog.csdn.net/shenghuaday/article/details/788779491.基本概念MDK(keil)的代码四段分类keil编译后code存储程序代码的RO-data存储const常量和指令,RW-data存储初始化值不为0的全局变量,ZI-data含义存储未初始化的全局变量或初始化值为0的全局变量所以有mcu的 flash实际存储数据Code RO Data RW Data存储 RAM大小 RW-dataZI-data内存;这个是MDK编译之后能够得到的每个段的大小也就能得到占用相应的FLASH和RAM的大小但是还有两个数据段也会占用RAM但是是在程序运行的时候才会占用那就是堆和栈。在stm32的启动文件.s文件里面就有堆栈的设置其实这个堆栈的内存占用就是在上面RAM分配给RW-dataZI-data之后的地址开始分配的。堆:是编译器调用动态内存 分配的内存区域。栈:是程序运行的时候局部变量的地方所以局部变量用数组太大了都有可能造成栈溢出。堆栈的大小在编译器编译之后是不知道的只有运行的时候才知道所以需要注意一点就是别造成堆栈溢出了,不然就等着hardfault找你吧。不理解的也可以去看我之前的博客有一个关于hardfault的查询帮助信息2)一个程序本质上都是由 bss段、data段、text段三个组成的在当前的计算机程序设计中是很重要的一个基本概念。而且在嵌入式系统的设计中也非常重要牵涉到嵌入式系统运行时的内存大小分配存储单元占用空间大小的问题C语言之类的程序编译完成之后已初始化的全局变量保存在.data 段中未初始化的全局变量保存在.bss 段中text和data段都在可执行文件中在嵌入式系统里一般是固化在镜像文件中由系统从可执行文件中加载而bss段不在可执行文件中由系统初始化bss段bss段bss segment通常是指用来存放程序中未初始化的全局变量的一块内存区域。bss是英文Block Started by Symbol的简称。bss段属于静态内存分配。data段数据段data segment通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。text段代码段code segment/text segment通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定并且内存区域通常属于只读(某些架构也允许代码段为可写即允许修改程序)。在代码段中也有可能包含一些只读的常数变量例如字符串常量等。堆heap堆是用于存放进程运行中被动态分配的内存段它的大小并不固定可动态扩张或缩减。当进程调用malloc等函数分配内存时新分配的内存就被动态添加到堆上堆被扩张当利用free等函数释放内存时被释放的内存从堆中被剔除堆被缩减。栈(stack)栈又称堆栈是用户存放程序临时创建的局部变量也就是说我们函数括弧“{}”中定义的变量但不包括static声明的变量static意味着在数据段中存放变量。除此以外在函数被调用时其参数也会被压入发起调用的进程栈中并且待到调用结束后函数的返回值也会被存放回栈中。由于栈的先进先出(FIFO)特点所以栈特别方便用来保存/恢复调用现场。从这个意义上讲我们可以把堆栈看成一个寄存、交换临时数据的内存区。3堆栈的例子--中断压入FlashSRAM寄存器 和输入输出端口被组织在同一个4GB的线性地址空间内。可访问的存储器空间被分成8个主要块每个块为512MB。FLASH存储下载的程序。SRAM是存储运行程序中的数据。所以只要你不外扩存储器写完的程序中的所有东西也就会出现在这两个存储器中。Stm32有通用寄存器 R0‐ R15 以及一些特殊功能寄存器,其中包括了堆栈指针寄存器。当stm32正常运行程序的时候来了一个中断CPU就需要将寄存器中的值压栈到RAM里然后将数据所在的地址存放在堆栈寄存器中。等中断处理完成退出时再将数据出栈到之前的寄存器中这个在C语言里是自动完成的。4malloc 和 free实现内存管理管理ram内存管理是指软件运行时对计算机内存资源的分配和使用的技术。其最主要的目的是如何高效快速的分配并且在适当的时候释放和回收内存资源分配malloc 原理当指针 p 调用 malloc 申请内存的时候先判断 p 要分配的内存块数m然后从第 n 项开始向下查找直到找到 m 块连续的空内存块即对应内存管理表项为 0然后将这 m 个内存管理表项的值都设置为 m标记被占用最后把最后的这个空内存块的地址返回指针 p完成一次分配。注意如果当内存不够的时候找到最后也没找到连续的 m 块空闲内存则返回 NULL 给 p表示分配失败释放free原理当 p 申请的内存用完需要释放的时候调用 free 函数实现。free 函数先判断 p 指向的内存地址所对应的内存块然后找到对应的内存管理表项目得到 p 所占用的内存块数目 m内存管理表项目的值就是所分配内存块的数目将这 m 个内存管理表项目的值都清零标记释放完成一次内存释放。————————————————版权声明本文为CSDN博主「xiaoxilang」的原创文章遵循CC 4.0 BY-SA版权协议转载请附上原文出处链接及本声明。原文链接https://blog.csdn.net/xiaoxilang/article/details/86093637