嵌入式內存分佈詳解

前言

硬件程序調試比較看重內存的分佈情況,可以通過編譯輸出文件來分析運行時的數據結構
如有疑問,歡迎指正,謝謝

內存分佈圖

  • 代碼段 (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段不保存到目標文件中,所以不佔用目標文件的任何空間
  • 數據段保存到目標文件中
  • 局部變量在運行時進行創建
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章