You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何启动文件需将.data与.bss段从Flash复制到SRAM?

为什么MCU启动时要把.data/.bss段从Flash复制到SRAM?

首先得明确MCU的两种核心存储介质的差异:

  • Flash:非易失性存储,上电后内容保留,但读写速度慢,且不适合频繁随机写入(擦写寿命有限)。
  • SRAM:易失性存储,掉电数据丢失,但读写速度极快,支持高效随机存取,是MCU运行时处理变量、临时数据的理想载体。

先看.data段:带初始值的全局/静态变量

.data段存储的是有明确初始值的全局变量、静态变量(比如int g_count = 5;)。
这些初始值会在编译烧录阶段被写入Flash(因为Flash能保存数据),但MCU运行时需要快速读写这些变量——总不能每次修改g_count都去Flash里操作,不仅速度慢,还会损耗Flash寿命。所以必须在启动阶段把Flash里的.data初始值复制到SRAM对应的区域,让程序后续直接操作SRAM里的变量。

再看.bss段:未初始化/初始值为0的全局/静态变量

.bss段存储的是未初始化或显式设为0的全局、静态变量(比如int g_temp;或者int g_flag = 0;)。
SRAM上电后内部是随机的脏数据,但C语言标准要求这类变量默认初始化为0。因为所有值都是0,没必要在Flash里占用存储空间存一堆0,所以启动阶段不需要复制数据,只需要把SRAM中.bss对应的区域全部清0即可——这一步和.data的复制同属启动初始化流程。

具体的复制/清0机制

编译链接时,链接器会自动生成几个关键地址符号(这些符号会被启动文件引用):

  • __data_start:SRAM中.data段的起始地址
  • __data_end:SRAM中.data段的结束地址
  • __data_load_start:Flash中.data初始值的存储起始地址
  • __bss_start:SRAM中.bss段的起始地址
  • __bss_end:SRAM中.bss段的结束地址

启动文件里的汇编代码会执行两个核心操作:

  1. 复制.data段:
    通过循环将Flash中__data_load_start开始的数据,逐字节(或按字)复制到SRAM的__data_start区域,直到覆盖整个.data段。对应C逻辑大概是:
    char *src = (char*)__data_load_start;
    char *dest = (char*)__data_start;
    while (dest < __data_end) {
        *dest++ = *src++;
    }
    
  2. 清0.bss段:
    通过循环把SRAM中__bss_start到__bss_end的区域全部设为0。对应C逻辑大概是:
    char *bss_ptr = (char*)__bss_start;
    while (bss_ptr < __bss_end) {
        *bss_ptr++ = 0;
    }
    

这两步操作必须在main()函数执行前完成,否则程序用到的全局/静态变量会是错误值,直接导致逻辑异常。

内容的提问来源于stack exchange,提问作者Sudhir Patel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 07:13:33