編譯就是把預處理完的檔案進行一系列的詞法分析、語法分析、語義分析及優化後生產相應的彙編**檔案。
gcc 這個命令只是後台程式的包裝,它會根據不同的引數要求去呼叫預編譯編譯程式cc1、彙編器as、鏈結器來ld。將彙編**轉變成機器可以執行的指令
詞法分析
首先源**程式被輸入到掃瞄器(scanner)
,它運用一種類似有限狀態機(finite state machine)
的演算法將源**的字串行分割成一系列的記號(token)
語法分析
語法分析器(grammar parser)將對由掃瞄器產生的記號進行語法分析,產生語法樹(syntax tree)
,整個過程採用長下文無關語法(context-free grammar)
的分析手段。語法樹就是以表示式(expression)
為及節點的樹。
語義分析
由語義分析器(semantic analyer)
來完成。所能分析的語義是靜態語義(static semantic)
,通常包括宣告和型別的匹配、型別的轉換。
中間語言生成
原始碼級優化器(source code optimizer)
將整個語法樹轉換成中間**(intermediate code)
目標**的生成與優化
源**級優化器產生中間**標誌著下面的過程都屬於編輯器後端,主要包括的**生成器(code generator)
和目標優化器(target code optimizer)
。**生成器將中間**轉換目標機器碼。
鏈結鏈結的主要過程包括:位址和空間分配(adress and storage allocation)
、符號決議(symbol resolution)
和重定向(relocation)
等步驟。
目標檔案的內容至少有編譯後的機器指令**,資料。還有鏈結時所需要的資訊,如符號表,除錯資訊,字串等。
自定義段
gcc提供了乙個擴充套件機制,使得程式設計師可以指定變數所處的段:
_attribute_((section(「foo」))) int global = 42;我們在全域性變數或者函式之前加上「_attribute_((section(「name」)))」屬性就可以把相應的變數或者函式放到以「name」作為段名的段中。_attribute_((section(「bar」))) void foo ( )
elf檔案結構描述
elf檔案結構圖
elf header
.text
.data
.bss
other sections…
section header table
string tables
symbol tables
…1.空間與位址分配
主要有兩種方式:按序疊加和相似段合併。按序疊加
會造成記憶體空間大量的內部碎片。所以乙個更實際的方法是將相同性質的段合併在一起,叫做相似段合併
。比如將所有輸入檔案的「.text」段合併到輸出檔案的「.text」段。使用這相思段合併方法的鏈結器一般都採用一種叫兩步鏈結(two-pass linking)
的方法,也就說整個過程分兩步。
空間與位址分配
符號解析與重定位
程式設計師的自我修養
一忌 輕易言敗,沒有自信 沒有永不放棄精神的程式設計師,只是乙個有程式設計師名號的假程式設計師。乙個真正的程式設計師,知道在程式設計的過程中,可能會遇到不計其數的困難和問題,可能有極多的挫折和失敗,而成功只有一次。就為解決乙個問題,我們可能連續十幾甚至幾十小時的坐在計算機前不停的工作。乙個問題解決了...
程式設計師的自我修養
一忌 輕易言敗,沒有自信 沒有永不放棄精神的程式設計師,只是乙個有程式設計師名號的假程式設計師。乙個真正的程式設計師,知道在程式設計的過程中,可能會遇到不計其數的困難和問題,可能有極多的挫折和失敗,而成功只有一次。就為解決乙個問題,我們可能連續十幾甚至幾十小時的坐在計算機前不停的工作。乙個問題解決了...
程式設計師的自我修養
對合作夥伴的尊重與包容 每個人的水平必然是不相同,大家各有擅長,並且在不斷進步中。所以遇到同事或者合作的友商犯了比較低階 對你來說可能是 的錯誤是很正常的事情,我們更多的是應該給與尊重與包容,而不是嘲笑或者消極對待。在不斷的鼓勵同事和合作夥伴之後,能感受到大家對我的信賴,特別是和友商的合作變得非常的...