首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言執行時資料佈局:ELF 區段、記憶體映射與段機制

     編輯:關於C語言

可執行檔案格式

現代 Linux 系統採用 ELF (Executable and Linkable Format)。查看檔案類型:

$ file hello.ko
hello.ko: ELF 32-bit LSB relocatable, ARM, version 1 (SYSV), not stripped

三大核心區段

區段內容size 輸出欄位佔檔案空間
.text (代碼段)機器指令、唯讀資料text是
.data (資料段)已初始化的全域/靜態變數data是
.bss (BSS段)未初始化或初始為 0 的全域/靜態變數bss否(僅記錄大小)

size 指令輸出範例

$ size hello.ko
   text    data     bss     dec     hex filename
    224     300       0     524     20c hello.ko

a.out 記憶體映射佈局(由低至高)

+------------------------+
|      Stack (堆疊)      |  高位址,向下增長,區域變數、參數、返回位址
|                        |
|      Heap (堆)         |  向上增長,malloc/new 動態分配
|                        |
|      Unmapped Hole     |  保護區,捕捉空指標存取
+------------------------+
|      .bss (BSS段)      |  零初始化,緊接 .data 之後
+------------------------+
|      .data (資料段)    |  已初始化全域/靜態變數
+------------------------+
|      .text (代碼段)    |  指令碼,唯讀,可共享
+------------------------+
|      ELF Header        |  魔數、程式進入點、區段表位置
+------------------------+  低位址(通常 0x08048000 或隨機化基址)

驗證實驗:Linux 核心模組

// hello.c
#include <linux/init.h>
#include <linux/module.h>

MODULE_LICENSE("GPL");

static int __init hello_init(void)
{
    printk(KERN_WARNING "Hello world!\n");
    return 0;
}

static void __exit hello_exit(void)
{
    printk(KERN_WARNING "Goodbye!\n");
}

module_init(hello_init);
module_exit(hello_exit);

編譯後 size 變化觀察

程式碼變更textdatabss說明
原始2243000基準
加 int i; (未初始化全域)2243008bss +8 bytes (2個int)
加 int m = 2; (非零初始化)2243088data +8 bytes
加 static int j; (未初始化靜態)2243088bss 不變(編譯器最佳化?)
函數內大陣列 int arr[1000];2243088區域變數不在可執行檔,運行時棧上分配

關鍵結論

  • 區域變數不存在可執行檔中,運行時於堆疊分配
  • 全域/靜態變數:未初始化或為 0 → .bss;非零初始化 → .data
  • .bss 不佔檔案空間,載入器根據記錄大小在記憶體中劃分並歸零
  • 使用者進程虛擬位址空間最低端(通常 64KB)故意不映射,用於捕捉空指標解參考
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved