嵌入式内存分布详解

前言

硬件程序调试比较看重内存的分布情况,可以通过编译输出文件来分析运行时的数据结构
如有疑问,欢迎指正,谢谢

内存分布图

  • 代码段 (Text segment):存放程序执行代码的区域,设计在低地址防止堆栈溢后覆盖现象,嵌入式系统中也就是ROM区
  • 初始化数据段(Initialized data segment):简称data段,存放程序中已经初始化全局初始化静态变量
  • 未始化数据段(Uninitialized data segment):简称bss段,存放程序中未初始化全局未初始化静态变量,该区域会在程序载入时由内核清零
  • 栈(Stack):存放局部变量,自动分配与释放,函数调用时进行内存的分配,调用结束时进行释放
  • 堆(Heap):动态内存块,主动分配(malloc/realloc),需要手动释放(free);可以使用brk和SBR调整大小
    在这里插入图片描述

代码论证

1. C源码样列

#include <stdio.h>
int main(void)
{
    printf("Memory Test!");
    return 0;
}
  • 使用GCC编译后,代码段text占用97字节,初始化数据段data为0字节,未初始化数据段bss占用0字节
    在这里插入图片描述

2. 代码上增加不初始化静态全局变量

#include <stdio.h> 
static int a;
int main(void) 
{ 
    return 0; 
} 
  • 使用GCC编译后,未初始化数据段bss增加到4字节,刚好是一个整型变量的占用空间
    在这里插入图片描述

3. 增加全局变量并赋初值

#include <stdio.h> 
static int a;
int b = 1;
int c = 2;
int main(void) 
{ 
    return 0; 
} 
  • 使用GCC编译后,未初始化数据段bss仍然为4字节,初始化数据段data为8字节
    在这里插入图片描述

4.分析目标文件

#include <stdio.h>
static int a;
int b;
int c = 1;
int d = 2;

const char *str = {"Memory Test1"};

int main(void)
{
    int e = 0;
    e += 1;
    printf("%s",str);
    return 0;
}

通过GCC进行编译,通过objdump指令查看可执行文件
在这里插入图片描述

  • .text对应的是汇编的指令
  • .data数据段对应的就是全局变量c、d,值分别为1与2
  • .rodata段存放了Memory Test1字符串常量
  • .bss段未打印,不占用目标文件

在这里插入图片描述
在这里插入图片描述

  • 上图中.bss段大小为4,但是代码定义了两个未初始化的变量,这个和编译器具体实现有关系

结论

  • BSS段不保存到目标文件中,所以不占用目标文件的任何空间
  • 数据段保存到目标文件中
  • 局部变量在运行时进行创建
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章