首頁>技術>

驗證1:初始化了的"靜態變數和全域性變數"儲存在data段

下面是用來驗證的例子:

#include<stdio.h>int global_init_value=8;int global_no_init_value;static int static_global_init_value=9;static int static_global_no_init_value;int main(){    int main_init_value = 1;    static int static_main_init_value = 10;    static int static_main_noinit_value;    return 0;}
int global_init_value=8;static int static_global_init_value=9;static int static_main_init_value = 10

上面3個欄位符合, 初始化了的"靜態變數和全域性變數", 接下來驗證它們存在於data段。

1. 用 readelf -S test.o 輸出所有段資訊

圖1

由上圖可知:data段的段索引為2,處於test.o檔案0x54位元組處,長度為0xC(十進位制12);

2. 用readelf -s test.o輸出test.o中的符號資訊:

圖2

由上圖可知:變數static_global_init_value, static_main_init_value, global_init_value 的段索引為2,也就是在data段,因為每個int佔4個位元組所以段大小為3*4=12位元組,跟圖1中data段的大小可以對上。

3. 用hexdump test.o以十六進位制格式檢視test.o檔案

圖3

由上圖可知:從0x54開始的12位元組資料為0008 0000 0009 0000 000a 0000, 每個int佔4位元組,也就是十進位制的8, 9, 10, 對應上了global_init_value, static_global_init_value, static_main_init_value的初始值。

結論初始化了的"靜態變數和全域性變數"的初始值確實儲存在data段。沒有初始化的"靜態變數和全域性變數"確實沒儲存在data段。驗證2:沒有初始化的"靜態變數和全域性變數"儲存在bss段, 且初始值為0

同理,由圖2可知,static_global_no_init_val, static_main_noinit_value 的段索引為3,也就是在bss段,而由圖1可知,bss段的大小為8位元組,剛好為2個int。由此驗證了,沒有初始化的"靜態變數和全域性變數"儲存在bss段。

為什麼靜態變數跟全域性變數要根據是否初始化儲存在不同的段

圖1bss段與下個段(comment段)的偏移量均為0x60,說明bss段在test.o中並沒有佔任何位元組,但data段佔用了12位元組,所以分出bss段是為了減小test.o檔案的大小,系統會根據bss段的大小分配記憶體,並把記憶體的值初始化為0。

9
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 極簡化ES資料同步,終於從繁瑣重複的程式碼裡脫身了