通過 arm-linux-objdump -D 反彙編 ELF 文件,可直觀觀察變量在各段的分布。本文以一個綜合示例演示全局/靜態變量、常量、字面量的歸屬規律。
#include <stdio.h>
#define VAR 0xFF
int a = 0;
static int b = 0;
int c = 10;
static int d = 20;
const int finalone = 10;
const int final;
int main(void) {
char *hell = "hhhhhhh";
const int finaltwo = 50;
static int f = 0;
static int k = 10;
int aa;
int bb = 10;
printf("VAR = %d\n, finalone = %d, finaltwo = %d", VAR, finalone, finaltwo);
}
Disassembly of section .data: 00011028: 11028: 0000000a 0001102c : 1102c: 00000014 00011030 : 11030: 0000000a
c(全局初始化 10)、d(static 初始化 20)、k(static 初始化 10)位於此段。Disassembly of section .bss: 0001103c : 1103c: 00000000 00011040: 11040: 00000000 00011044 : 11044: 00000000
a(全局 0)、b(static 0)、f(static 0)、final(未初始化 const)均在 .bss。Disassembly of section .rodata: 0000848c: 848c: 0000000a 8490: 68686868 ... // "hhhhhhh"
finalone(全局 const 初始化 10)、字符串 "hhhhhhh" 存放於此。83fc: e3a010ff mov r1, #255 ; #define VAR 0xFF → 立即數嵌入指令 83cc: e3a03032 mov r3, #50 ; const int finaltwo = 50 → 棧上分配,運行時賦值
#define 宏在預處理階段文本替換,編譯為立即數,直接嵌入指令流,佔用 .text 空間,每處使用一份拷貝。const 變量在編譯期確定值,存儲於 .rodata/.bss,運行期只有一份拷貝,有類型檢查。| 特性 | #define 宏 | const 常量 |
|---|---|---|
| 處理階段 | 預處理(文本替換) | 編譯(符號表) |
| 內存分布 | 立即數,分散在 .text | 集中在 .rodata/.bss,單一拷貝 |
| 類型安全 | 無類型 | 有類型 |
| 調試可見性 | 不可見(符號表無) | 可見 |
理解這些分布規律,對嵌入式優化內存佔用、定位符號衝突、逆向分析極具指導意義。