《程式設計師自我修養》讀書筆記

胖白白發表於2024-05-18

目錄
  • 虛擬地址空間(虛擬記憶體)佈局
  • 編譯與連結
    • 例子原始碼
    • 看看obj檔案的組成格式
      • 主要的段
      • 全部的段
      • 組成格式:頭資訊+段
  • 一些概念和命令的總結
    • 概念
    • 命令

虛擬地址空間(虛擬記憶體)佈局

image

  1. bss段節省的是檔案的空間,不是虛擬地址空間

  2. 指令段和資料段在程式執行起來後是不變的,不可伸縮

  3. 從0地址開始到0x08048000的128M地址空間,禁止訪問,比如這種操作:

    char *p = NULL;
    ...
    strlen(p);  // 訪問出錯
    

編譯與連結

下圖說明了編譯與連結的核心步驟,後面會用一個例子來說明其中的關鍵資訊

image

連結器,只對global 符號處理,不對local 符號處理

例子原始碼

int g_data1 = 10;
int g_data2 = 0;
int g_data3;

static int g_data4 = 11;
static int g_data5 = 0;
static int g_data6;

int main()
{
    int a = 12;
    int b = 0;
    int c;

    static int d = 13;
    static int e = 0;
    static int f;

    return 0;
}

PS:上面的原始碼哪些是指令,哪些是資料?紅色的是資料,綠色的是指令

區域性變數、函式屬於指令

全域性變數、靜態區域性變數屬於資料

image

看看obj檔案的組成格式

主要的段

gcc -c main.c得到main.o檔案,使用objdump -h main.o看看obj檔案的段:

image

VMA: 虛擬地址

LMA: 載入地址

VMALMA此時都是0,說明編譯步驟不給符號分配記憶體地址,符號解析完成後才會分配(連結時)

File off:地址偏移

Algn:對齊位元組

結合ELF headerFile offAlgn可以算出每個段在虛擬地址空間佔的大小,這裡也可以發現.bss段不佔檔案空間(虛擬地址空間需要佔,否則符號放哪裡呢)

全部的段

readelf -S main.o可以檢視所有的段

image

組成格式:頭資訊+段

  • file main.o檢視檔案屬性,obj檔案為可重定位的檔案,不可執行

image

  • readelf -h main.o顯示obj檔案開始的檔案頭資訊

image

  • 結合前面的段,加上這裡的ELF Header,可以看出obj檔案的組成格式:

一些概念和命令的總結

概念

  1. CPU的位數是一次效能載入的最長的整數寬度,ALU的寬度,資料匯流排的條數
  2. 虛擬記憶體(虛擬地址空間)的大小 =2^CPU位數

命令

image

相關文章