gcc編譯c**會有四個階段:
預處理:將c**中的標頭檔案和巨集進行處理
彙編:把彙編**轉化成機器指令,並以特定的二進位制格式輸出儲存在 .o這樣的目標檔案中
流程圖:
參考閱讀:
3. c程式分析
gcc -e hello.c -o hello.i //預處理
gcc -s hello.i -o hello.s //編譯
gcc -c hello.s -o hello2.o //彙編
gcc hello.o -o hello //鏈結
attention:直接輸出就使用 gcc -s hello.i -o - 即可,加優化選項就是-o1
readelf -h hello.o //可以檢視目標檔案標頭檔案的內容, 定義在"/usr/include/linux/elf.h"
objdump -h hello.o //命令只是顯示關鍵段,省略了輔助性的段。」readelf -s」命令顯示的更完整
readelf -s hello.o //命令可以顯示所有段(bss data text)的內容
nm -a hello.o //可以顯示所有變數在哪個區域
weiwei@weiwei-ubuntu:~/tools$ nm -a hello2.o
hello2.o:0000000000000004 c aaaaa
hello2.o:0000000000000000 b bbbbb
hello2.o:0000000000000008 b ddddd.2061
hello2.o:0000000000000004 c eeeaaaaa
hello2.o:0000000000000004 b eeeebbb
hello2.o:0000000000000028 c exec1
hello2.o:0000000000000000 t main
hello2.o: u printf
hello2.o: u puts
第二列:指明符號值(位址)
第三列:符號型別:b--->bss c--->common t--->test(所有的可以見linux 核心完全剖析 p71)
第四列:對應的符號名稱
int aaa = 1;
const int bbb = 1;
int ccc;
const int ddd;
int eee = 0;
const int fff = 0;
a.out:0000000000601020 d aaa
a.out:00000000004005fc r bbb
a.out:0000000000601040 b ccc
a.out:000000000060103c b ddd
a.out:0000000000601038 b eee
a.out:0000000000400600 r fff
全域性變數:
b--->bssbss是指那些沒有初始化的和初始化為0的全域性變數,bss型別的全域性變數只佔執行時的記憶體空間,而不佔檔案空間
r---->rodata ro代表read only,即唯讀資料(const),執行時直接讀取rom記憶體,無需要載入到ram記憶體中
d--->datadata指那些初始化過(非零)的非const的全域性變數。data型別的全域性變數是即佔檔案空間,又占用執行時記憶體空間的
C程式編譯過程
題記 前幾天去華為面試實習生,面試官問了個問題,讓我說出乙個程式的詳細編譯過程,當時磕磕絆絆說了一堆東西,事後自己都不知道當時說了什麼,慚愧。c語言編譯過程 編譯,編譯程式讀取源程式 字元流 對之進行詞法和語法的分析,將高階語言指令轉換為功能等效的彙編 再由匯程式設計序轉換為機器語言,並且按照作業系...
C 程式編譯過程
首先是編譯過程整體簡介 編譯過程主要分為 4個過程 1 編譯預處理 預編譯程式完成的工作,可以說成是對源程式的 替換 工作。經過這個過程,生成乙個沒有巨集定義 沒有條件編譯指令 沒有特殊符號的輸出檔案。2 編譯 優化階段 通過詞法分析 語法分析,在確認所有的指令都符合語法規則之後,將其翻譯成等價的中...
C程式編譯過程
接觸程式設計還在麼長時間,還沒有好好理解下一段 從.c到可執行程式的過程。先看一下gcc的常用引數 引數詳解 c 只啟用預處理,編譯,和彙編,也就是他只把程式做成obj檔案 例子用法 gcc c hello.c 他將生成.o的obj檔案 s 只啟用預處理和編譯,就是指把檔案編譯成為彙編 例子用法 g...