STM32堆栈的大小及内存四(五)区的分析

这篇具有很好参考价值的文章主要介绍了STM32堆栈的大小及内存四(五)区的分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

STM32堆栈的大小及内存四(五)区的分析

1、设置堆栈空间的大小

1.1、STM32堆栈空间大小

一般在编程时,我们都不需要考虑堆栈空间的大小,因为在启动文件中都对堆栈空间的大小进行了设置。

1.1.1、直接修改启动文件

如以下截取stm32启动文件部分汇编代码,Stack栈的大小为:0x400(1024Byte),Heap堆的大小为:0x200(512Byte)。

; Amount of memory (in bytes) allocated for Stack
; Tailor this value to your application needs
; <h> Stack Configuration
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Stack_Size		EQU     0x400  
                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp

; <h> Heap Configuration
; <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Heap_Size       EQU     0x200
                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit

这也是为什么一个空的的工程编译后,RAM的空间也占用了1.6K的原因,因为堆栈的空间均分配在RAM中。可以在map文件中查看具体占用大小

1.1.2、修改keil Configuration进行设置

如下图所示,可以在打开启动文件页面后,点击Configuration Wizard,可在Option的设置框中设置堆栈空间的大小
STM32堆栈的大小及内存四(五)区的分析

1.2、堆栈的分析

1.2.1、堆栈的溢出

若局部变量较多、定义的数据长度,加一起的空间大于**栈(Stack)**的空间,则会导致栈溢出,程序运行结果与预期的不符或程序跑飞。这时需要手动的调整栈的大小,来复合我们的需求

若使用了malloc动态分配内存空间时,大于设置的**堆(Heap)**的空间。会导致溢出,需要调整堆的大小

1.2.2、堆栈的增长方向

一般堆是由低地址往上(高地址)增长栈是由高地址向下(低地址)增长。都是连续的,C语言不提供内存保护机制类似的功能,如果一直堆一直增长,栈一直申请,然后就会导致栈溢出,程序崩溃

1.2.3、堆栈的首地址

一般堆栈的起始地址是不固定的,是根据用户定义的变量的数目和大小决定的,是编译器自动分配的,内存首先存放/开辟全局变量区域,然后开辟栈区最后开辟堆区

栈首地址=全局区域大小+栈大小(Stack_Size)

1.2.4、堆栈的区别

  • 存储的内容:
    • 栈存局部变量、函数参数等
    • 堆存储使用 new、malloc 申请 的变量等
  • 申请的方式:
    • 栈内存由系统分配、释放
    • 堆内存由自己申请、释放
  • 申请后系统的响应:(带操作系统的环境)
    • 栈——只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出
    • 堆——首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申 请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空 闲结点链表 中删除,并将该结点的空间分配给程序
  • 申请大小的限制:
    • 单片机一般堆栈大小都是固定
    • 有操作系统情况下,堆的大小可以随意增长,收到硬件的显示
  • 申请效率的对比:
    • 栈由系统自动分配,速度较快
    • 堆使用 new、malloc 等分配,较慢

2、内存四(五)区

2.1、内存四区和内存五区的区别

其实内存四区和内存五区所指的东西是一样的,对于内存四区而言,其只是把全局区(静态区)和常量区合并为一个数据区而已,其实内容都是完全一样的

2.1.1、内存四区

栈区、堆区、数据区(全局区(静态区)、常量区)、代码区

2.1.2、内存五区

栈区、堆区、全局区(静态区)、常量区、代码区

2.2、内存四区具体含义

2.2.1、栈区

  • 系统自动分配,函数结束自动释放,也可以说由编译器自动分配和释放
  • 局部变量、局部常量、函数参数
  • 特点:进栈出栈有相应的计算机指令支持,而且分配专门的寄存器存储栈的地址,效率分高,内存空间是连续的,但栈的内存空间有限

2.2.2、堆区

  • 使用malloc()/new()申请的内容存储在堆区
  • 由程序员手动分配,手动释放,或者程序结束系统回收,不释放就会产生内存泄漏

2.2.3、全局区(静态区)

全局变量、静态变量(全局or局部)

  • 全局区分为两个段:
    • data段:存储初始化的全局变量、初始化的静态变量
    • bss段:存储未初始化的全局变量、未初始化的静态变量
  • 调用函数结束不会被销毁
  • 其中BSS段会在程序执行前**,将内容全部置为0,**所以未初始化的全局变量和静态变量的值都为0

2.2.4、常量区

  • 存放常量,字符串常量和其他常量的存储位置,而且不允许修改
  • 程序结束之后由系统释放

2.2.5、代码区

  • 要存放程序中的代码(二进制),属性是只读
  • 又称text段

2.3、代码示例

int a = 0;                  //全局初始化区  
char *p1;                   //全局未初始化区 
int add(int a; int b)
{
    int sum = 0;            //栈
    static temp;            //全局(静态)未始化区  
    sum = a+b;
    return sum;
}
int main()
{     
    int b;                  //栈     
    char s[] = "abc";       //栈   
    char *p2;               //栈      
    char *p3 = "123456";    //123456\0在常量区,p3在栈上     
    static int c = 0;       //全局(静态)初始化区     
    p1 = (char *)malloc(10);     
    p2 = (char *)malloc(20); //分配得来得10和20字节的区域就在堆区     
    strcpy(p1, "123456");    //123456\0放在常量区, 编译器可能会将它与p3所指向的"123456"优化成一块    
    return 0; 
}

参考连接

https://www.e-learn.cn/topic/3842454
https://blog.csdn.net/u011764302/article/details/103368274文章来源地址https://www.toymoban.com/news/detail-452662.html

到了这里,关于STM32堆栈的大小及内存四(五)区的分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32-程序占用内存大小计算

    STM32中程序占用内存容量 Keil MDK下Code, RO-data,RW-data,ZI-data这几个段: Code存储程序代码。 RO-data存储const常量和指令。 RW-data存储初始化值不为0的全局变量。 ZI-data存储未初始化的全局变量或初始化值为0的全局变量。 占用的Flash=Code + RO Data + RW Data; 运行消耗的最大RAM= RW-data+ZI-dat

    2024年02月04日
    浏览(46)
  • C语言-内存分布(STM32内存分析)

    根据动静特性可以将内存分为 动态区域 和 静态区域 , 代码段 (Code)、 只读数据段 (RO data)、 读写数据段 (RW Data)、 未初始化数据段 (BSS)属于 静态区域 。 堆 和 栈 属于 动态区域 。 文本段 (Text / 只读区域 RO) 通常代码段和只读数据段合成为文本段(Text), 包含实

    2024年02月11日
    浏览(37)
  • C语言内存分区及堆栈对比分析

    下面是一篇关于C语言内存分区的博文,包括5个分区的介绍、堆栈的对比分析以及它们各自的优劣势。希望对您有所帮助。 在C语言中,内存分为不同的区域,每个区域都有其特定的用途和访问规则。主要的内存分区包括:代码区、全局区(静态区)、堆区、栈区和常量区。在

    2024年02月09日
    浏览(33)
  • stm32以及freertos 堆栈解析

    以前在mcu编程的时候没有太注意堆栈的情况,只知道需要将堆栈设置的大一点。现在逐步使用freertos,在freertos中也有关于堆栈的设置,freertos的堆栈和启动文件中的堆栈关系是什么?为了以后使用的无误,本次一次性把这些弄清楚。 堆栈是一个特定的存储区或者寄存器。一般

    2023年04月08日
    浏览(50)
  • STM32堆栈方面知识点

    最近弄json,发现经常的堆溢出,然后找问题。因为对STM32堆栈问题没有深刻认识,就花时间好好研究下了堆栈并且做了验证 1.栈地址区间确定 首先找到启动文件,我的启动文件在startup_stm32f40xx.s,一般的启动文件也都在startup_stm32fxxxx.s文件里 __initial_sp      这个参数是栈顶地

    2024年02月10日
    浏览(35)
  • stm32数据对齐、PRESERVE8、freertos堆栈

    避免数据在内存中跨边界存储,减少读取数据次数,提高效率,本质上是以空间换时间的做法 下图中属于同一水平位置的为同一边界 变量在同一边界里的一次存储周期就可以读取 一旦跨了上下两个边界来存储就需要至少两个存储周期来读取 根据存储器结构,如下图,参考链

    2024年02月11日
    浏览(40)
  • STM32 大小端与字节对齐使用记录

    串口数据包解析 接收到的数据包: 其中数据内容为: 我们设计的结构体 使用内容复制函数 想要的数据: 实际的数据: 解决方法: CMSIS都已经给你写好的,请看core_cm3.h 执行完这个代码后 我们希望 实际上 解决方法:

    2024年02月07日
    浏览(37)
  • 【STM32】STM32内存映射以及启动过程(超详细过程)

    下图是 STM32F103xCDE 型号的内存映射图。 由于 STM32 是 32 位,且其地址总线也为 32 根,所以其 理论能够寻找的地址大小为 4GB 。 从上图可以看出,左边的地址从 0x0000 0000 ~ 0xFFFF FFFF 的 4GB 是 STM32 理论分配的地址空间, STM32 实际上的空间大小 远远小于 4GB 的 。4GB 中又划分出了

    2024年02月11日
    浏览(41)
  • STM32 FreeRTOS 内存问题

    2024年02月09日
    浏览(39)
  • FreeRTOS内存管理 基于STM32

    目录 一、内存管理的基本概念 二、内存管理的应用场景 三、heap_4.c 1.内存申请函数 pvPortMalloc() 2.内存释放函数 vPortFree()  四、内存管理的实验 五、内存管理的实验现象       在计算系统中,变量、中间数据一般存放在系统存储空间中,只有在实际使用时才将 它们从存储空

    2024年02月14日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包