我們基本都知道乙個程式由**行再到最後被執行生成目標檔案,會經歷四個過程:1:預編譯(prepressing) 2.編譯(compilation) 3.彙編(linking)4.鏈結(assembly)但其中每個步驟都發生了什麼,還是不太清楚,今天我們就來學習了解下這個過程.
一.預編譯.(假設原檔案是.c檔案 .c------> .i檔案)
linux命令(gcc -e test.c -o test.i 或者 cpp test.c > test.i // test.i代表處理生成的.i檔案程式名)
預編譯主要處理那些源**檔案中以"#"的預編譯指令.如"#define" "#include".
1.#define定義的識別符號替換,#define定義的巨集也會發生替換.或者直接說#define的刪除,並展開巨集定義.
2.處理"#include"預編譯指令,將包含的標頭檔案插到該預編譯指令的位置,該過程是遞迴的.
3.處理所有條件預編譯指令,比如"#if ","#endif","else","#elif". 注意#pragma pack(8)設定預設對齊數在這個階段不會進行語法檢查.
4注釋的替換刪除 將注釋替換成了空格.
二.編譯(生成 .s檔案-->由彙編**組成)
linux命令(gcc -s test.i -o test.s)
1.語法檢查
2.語法分析(生成語法樹)
3.語義分析
4.符號彙總
三.彙編 (生成 .o檔案->生成機器可識別** objcode 也稱為目標檔案)
linux命令(gcc -c test.s -o test.o)
1.彙編**轉機器**
bss段: 未初始化的全域性變數和區域性靜態變數
bss段只是為未初始化的全域性變數好熱區域性靜態變數預留位置,不佔空間.
指令(函式)放在test段也就是**段
四.鏈結(生成a.out檔案,可執行檔案或者庫檔案)
1.合併段表.
2.符號表的合併和符號表的重定位.
程式的編譯 鏈結
在linux下,使用gcc來編譯hello world時,只使用最簡單的命令 gcc hello.c a.out hello world 但上述過程可以分解為4個步驟,即預處理 編譯 彙編 鏈結。預處理 預編譯 gcc e hello.c o hello.i 或者 cpp hello.c hello...
程式編譯鏈結
認識各種儲存部件 暫存器 記憶體 磁碟 暫存器 快取記憶體 記憶體 磁碟快取 磁碟 主存 儲存程序執行時的程式和資料 暫存器 速度最快,昂貴容量不大,一般以字為單位,只要存放指令一次操作的資料就夠了 儲存部件的層次 快取記憶體 一種速度比記憶體快的儲存裝置,一般同暫存器一樣整合在cpu中。存放記憶體...
程式的編譯和鏈結
一般來說,無論是c c 還是pas,首先要把原始檔編譯成中間 檔案,在windows下也就是 obj 檔案,unix下是 o 檔案,即 object file,這個動作叫做編譯 compile 然後再把大量的 object file合成執行檔案,這個動作叫作鏈結 link 編譯時,編譯器需要的是語法...