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

C語言運行時數據段佈局深度解析:從ELF到內存映射

     編輯:關於C

可執行文件格式與段概念

在 UNIX/Linux 系統中,編譯鏈接產出的可執行文件多採用 ELF(Executable and Linkable Format) 格式。早期 `a.out` 曾是組譯器輸出,現則為鏈接器輸出的統稱。可通過 `file` 指令確認:

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

目標文件三大核心段

使用 `size` 指令可查看三段大小:

$ size hello.ko
   text    data     bss     dec     hex filename
   224    300       0     524     20c hello.ko
段名別名存放內容備註
.text代碼段/文本段可執行指令只讀,多進程共享
.data數據段已初始化的全局/靜態變量讀寫,佔用文件空間
.bssBSS段未初始化的全局/靜態變量僅記錄大小,文件不佔空間,載入時清零

關鍵實驗驗證

以簡單內核模組 `hello.ko` 為例:

  1. 初始狀態:text=224, data=300, bss=0
  2. 新增 int i; int m=2; static int j; static int n=1; 後:text=224, data=300, bss=8

觀察發現:

  • 函數內局部變量不出現在可執行文件,運行時在棧上分配。
  • 全局未初始化變量(`i`)進 .bss;初始化為非零(`m=2`)進 .data;初始化為 0 也歸 .bss(編譯器優化)。
  • 靜態全局變量(`j`, `n`)在實測中未增大 .data/.bss,推測為交叉編譯工具鏈優化或段屬性差異,需結合具體工具鏈文檔確認。

進程虛擬地址空間佈局

高地址
┌─────────────────┐
│   堆棧段        │  ← 向下增長,存局部變量、參數、返回地址
│       ↓         │
│     空洞        │  ← 未映射區,捕獲空指針訪問
│       ↑         │
│   堆段          │  ← 向上增長,動態分配
├─────────────────┤
│   .bss 段       │  ← 緊接 .data,載入時清零
├─────────────────┤
│   .data 段      │  ← 已初始化全局/靜態變量
├─────────────────┤
│   .text 段      │  ← 只讀代碼
├─────────────────┤
│  a.out 魔數等   │
└─────────────────┘
低地址(前幾 KB 未映射)

載入器利用 mmap() 將各段映射至虛擬地址空間,.text/.data 直接映射文件內容,.bss 僅預留大小並清零。

總結

理解段機制有助於:

  • 分析程序體積、優化內存佔用
  • 排查段錯誤、內存越界
  • 嵌入式開發中控制鏈接腳本、精確佈局
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved