单片机内存结构解析:Flash、RAM、堆与栈详解及其相互关系
目录
前言 :
一、Flash:非易失性程序存储器
二、RAM:易失性数据存储器
三、堆(Heap):动态内存区域
四、栈(Stack):函数调用和局部变量区域
五、它们之间的关系和联系
前言 :
在嵌入式开发中,理解单片机的内存结构对于程序设计、资源管理和系统稳定性至关重要。STM32 单片机(以 STM32F103 系列为例)中包含多种类型的存储器资源,包括 Flash、RAM、堆(Heap)和栈(Stack)。本文将全面介绍它们的作用、存放内容以及它们之间的联系。
将结合下图进行讲解。

一、Flash:非易失性程序存储器
特性:
1.Flash 是非易失性存储器,即掉电后数据仍然保留。
2.在 STM32 中通常用于存储程序和常量。
3.Flash 地址起始于 (Start) 0x08000000是 STM32 的默认程序存储地址,大小(Size)为 0x10000 有 64KB Flash。
0x10000 (16进制) = 65535 (十进制) 字节 = 64 KB
存放内容:
1.程序代码 :编译后的机器指令。
2.只读常量数据 :如 const 修饰的变量、字符串等。
3.启动代码和中断向量表:在启动时从此处执行。
二、RAM:易失性数据存储器
特性:
1.RAM 是运行时内存,掉电后数据丢失。
2.RAM地址通常从 0x20000000 开始,大小(Size)为 0x5000 有 20KB RAM。
3.分为多个段:.data、.bss、堆(Heap) 和 栈(Stack)
存放内容:
(1) .data 段(初始化的全局/静态变量)
int counter = 5;
static uint8_t flag = 1;
(2) .bss 段(未初始化的全局/静态变量)
int sensor_value;
static char buffer[50];

(3) 堆(Heap)
用于动态内存分配(如 malloc()),由链接脚本指定起始地址,在运行时从 RAM 低地址向上增长。
(4) 栈(Stack)
用于函数调用、局部变量、返回地址保存等,从 RAM 高地址向下增长。
三、堆(Heap):动态内存区域
特性
1.运行时动态分配内存区域。
2.通常从 .bss 段之后开始向高地址增长
3.STM32 中使用 malloc()、calloc() 等函数分配,需启用 heap 区域。
存放内容
动态创建的数组、链表、缓冲区、对象等。
动态创建通常是指在程序运行时(而不是编译时)根据需要分配内存来创建数组、链表、缓冲区或对象。如用 malloc() / calloc() / realloc() 进行内存分配(来自堆)
四、栈(Stack):函数调用和局部变量区域
特性
1.自动管理内存,函数调用时分配,返回后释放。
2.从 RAM 的高地址向下增长,栈顶由 MSP(Main Stack Pointer)寄存器管理。
存放内容
1.函数的局部变量
2.函数返回地址(链接寄存器)
3.中断上下文保存(中断嵌套时保存 CPU 状态)
4.可在启动文件中配置栈大小。
五、它们之间的关系和联系
| 资源类型 | 属于哪类存储器 | 和 Flash 的关系 | 和 RAM 的关系 | 特点和用途 |
|---|---|---|---|---|
| Flash | 非易失性存储器 | 本身就是 Flash | 无直接关系 | 存储程序代码和常量 |
| RAM | 易失性存储器 | 启动时从 Flash 中拷贝 .data 段 |
是堆、栈、数据段的物理存储基础 | 运行时存储各种变量 |
| 堆(Heap) | RAM 的一部分 | 无 | 占用 RAM 空间,从低地址向上增长 | 存放运行时动态分配的内存 |
| 栈(Stack) | RAM 的一部分 | 无 | 占用 RAM 空间,从高地址向下增长 | 用于函数调用、局部变量等 |
1.Flash 和 RAM 的联系:
(1).程序运行前,启动代码会将 .data 段从 Flash 拷贝到 RAM;
(2).bss 段也在 RAM 中,由启动代码清零;
(3)Flash 中的代码运行时直接在 Flash 执行,常量可直接引用。
2.栈和堆 与 RAM 的关系:
(1)它们都是运行时依赖 RAM 的“逻辑区域”;
(2)栈是系统自动管理,堆是用户手动申请释放;
(3)如果堆和栈在运行时“撞车”(堆上增长、栈下增长,区域重叠)会导致系统崩溃
作者:S-码农