程序的段的存儲方式與存儲區域大小要求
程序的存儲和運行涉及 ROM(Flash/非易失性存儲器) 和 RAM(易失性存儲器) 的分配,不同段在存儲和運行時具有不同的特性。以下是詳細的分類和計算方式:
1. 程序文件的存儲方式
程序在 編譯后生成的二進制文件(如 .bin/.hex) 按照以下方式存儲在 ROM(Flash) 中:
段類型 | 存儲位置 | 說明 |
---|---|---|
Code段 | ROM | 存儲程序的可執行代碼(機器指令) |
RO_data段 | ROM | 存儲只讀數據(如 const 常量、字符串常量) |
RW_data段 | ROM | 存儲已初始化且非零的全局/靜態變量(初始值) |
ZI_data段 | 不存儲 | 僅記錄大小,運行時在 RAM 中初始化為零 |
關鍵點:
- ZI_data段 不會占用 ROM 空間,僅記錄其大小,由啟動代碼在 RAM 中初始化為零。
- RW_data段 的初始值存儲在 ROM 中,但運行時會被拷貝到 RAM(因為 RAM 可讀寫,而 ROM 不可寫)。
2. 程序運行時的內存布局
程序運行時,內存(RAM)會被劃分為以下部分:
段類型 | 存儲位置 | 說明 |
---|---|---|
Code段 | ROM 或 RAM | 通常直接從 ROM 執行,但某些系統可加載到 RAM(如 XIP 或加速執行) |
RO_data段 | ROM 或 RAM | 通常只讀,可直接從 ROM 訪問,但某些情況會加載到 RAM |
RW_data段 | RAM | 從 ROM 拷貝初始值到 RAM,運行時可修改 |
ZI_data段 | RAM | 由啟動代碼初始化為零 |
堆(Heap) | RAM | 動態內存分配(malloc/free ) |
棧(Stack) | RAM | 存儲局部變量、函數調用信息 |
關鍵點:
- RW_data段 必須加載到 RAM,因為 ROM 不可寫。
- ZI_data段 在 RAM 中分配并清零,不占用 ROM 空間。
- 堆和棧 在運行時動態增長,不占用 ROM 空間,但必須預留足夠的 RAM。
3. 存儲區域的大小計算
(1) ROM(Flash)大小計算
ROM 存儲的是 程序文件,其大小由以下部分組成:
ROM?大小=Code段+RO_data段+RW_data段(初始值)
\text{ROM 大小} = \text{Code段} + \text{RO\_data段} + \text{RW\_data段(初始值)}
ROM?大小=Code段+RO_data段+RW_data段(初始值)
- ZI_data段不占用 ROM,僅記錄大小。
- RW_data段 的初始值存儲在 ROM 中,但運行時會被拷貝到 RAM。
(2) RAM 大小計算
RAM 存儲的是 運行時數據,其最小需求為:
RAM?最小需求=RW_data段+ZI_data段
\text{RAM 最小需求} = \text{RW\_data段} + \text{ZI\_data段}
RAM?最小需求=RW_data段+ZI_data段
但實際 RAM 需求 必須更大,因為:
- 堆(Heap):動態內存分配(
malloc
/free
)需要額外空間。 - 棧(Stack):函數調用、局部變量、中斷處理等需要棧空間。
實際 RAM 需求:
實際?RAM?需求=RW_data段+ZI_data段+堆大小+棧大小
\text{實際 RAM 需求} = \text{RW\_data段} + \text{ZI\_data段} + \text{堆大小} + \text{棧大小}
實際?RAM?需求=RW_data段+ZI_data段+堆大小+棧大小
示例:
- 如果
RW_data = 2KB
,ZI_data = 4KB
,堆預留1KB
,棧預留1KB
:
最小?RAM=2+4=6KB實際?RAM=2+4+1+1=8KB \text{最小 RAM} = 2 + 4 = 6KB \\ \text{實際 RAM} = 2 + 4 + 1 + 1 = 8KB 最小?RAM=2+4=6KB實際?RAM=2+4+1+1=8KB
4. 啟動方式對存儲的影響
程序運行時,代碼和數據可以有不同的加載方式:
-
直接從 ROM 執行(XIP, eXecute In Place)
- Code段 和 RO_data段 直接從 ROM 讀取,不占用 RAM。
- RW_data段 從 ROM 拷貝到 RAM。
- ZI_data段 在 RAM 中初始化為零。
- 優點:節省 RAM,適用于 RAM 較小的嵌入式系統。
- 缺點:ROM 訪問速度可能比 RAM 慢。
-
全部加載到 RAM 執行
- Code段、RO_data段、RW_data段 全部從 ROM 拷貝到 RAM。
- ZI_data段 在 RAM 中初始化為零。
- 優點:執行速度更快(RAM 訪問快)。
- 缺點:占用大量 RAM,適用于 RAM 較大的系統(如 Linux 應用)。
5. 總結
分類 | ROM(Flash) | RAM |
---|---|---|
Code段 | ? 存儲 | ?(除非加載到 RAM 執行) |
RO_data段 | ? 存儲 | ?(除非加載到 RAM 執行) |
RW_data段 | ? 存儲初始值 | ? 運行時加載 |
ZI_data段 | ? 不存儲 | ? 運行時初始化為零 |
堆(Heap) | ? 不存儲 | ? 動態分配 |
棧(Stack) | ? 不存儲 | ? 運行時使用 |
存儲大小計算:
- ROM 大小 =
Code段 + RO_data段 + RW_data段(初始值)
- RAM 最小需求 =
RW_data段 + ZI_data段
- 實際 RAM 需求 =
RW_data段 + ZI_data段 + 堆 + 棧
適用場景:
- 嵌入式系統(RAM 小):直接從 ROM 執行(XIP)。
- 高性能系統(RAM 大):全部加載到 RAM 執行。
這樣,你可以根據目標設備的資源情況(ROM/RAM 大小)合理規劃內存布局。