程式設計師的自我修養學習筆記 第二章

2022-07-03 19:57:12 字數 1745 閱讀 7561

從原始檔到可以行檔案的過程

:預處理——編譯——彙編——鏈結

第一步預編譯:

$gcc  -e hello.c -o hello.i

或者$cpp hello.c > hello.i 

注:『-e』選項表示只進行預編譯;cpp是預編譯器

預編譯主要處理一『#』開頭的預編譯指令: 

將所有的"#define"刪除,並且展開所有的巨集定義

處理所有條件預編譯指令

處理"#include",將包含的檔案插入到該預編譯指令的位置。注意,這個過程是遞迴進行

刪除所有注釋

新增行號和檔名標識,以便於除錯和編譯產生的錯誤和警告

保留所有"#pragma"指令,編譯器需要使用它們

編譯: 

$gcc  -s  hello.i -o hello.s 

也可以將編譯和預編譯合併,通過乙個gcc提供的程式ccl來完成: 

$/usr/lib/gcc/usr/lib/gcc/i686-pc-cygwin/ccl   hello.c 

或者:$gcc  -s  hello.c -o hello.s

實際上gcc這個命令只是一些列後台程式的包裝,它會根據不同的引數要求去呼叫預編譯程式ccl、彙編器as、聯結器ld。

彙編:是將彙編**轉換為機器碼的過程

這樣來完成彙編: 

$as  hello.s  -o hello.o 

或者:$gcc  -c  hello.s  -o  hello.o 

或者:從.c檔案開始

$gcc  -c  hello.c  -o  hello.o

需要經過下面的一些命令來完成:

ld  -static  crt1.o  crti.o  crtbegint.o  hello.o  -start-group -lgcc   -lgcc_eh

-lc-end-group  crtend.o  crtn.o

注:到後面的時候記錄一下各個引數的作用,然後在這裡補充 

編譯器都做了什麼:

編譯過程一般可以分為6步:掃瞄、語法分析、語義分析、源**優化、**生成和目標**優化。

詞法分析: 

運用有限狀態機(finite state machine)可以輕鬆的將源**的字串行分割成一系列的記號。

此法分析產生的記號一般有一下幾類:關鍵字、識別符號、字面量(包含數字、字串等)和特殊符號(如加號、等號)

語法分析: 

語法分析器(grammar parser)將對由掃瞄器產生的記號進行語法分析,從而產生語法樹。

由語法分析器生成的語法樹就是以表示式為節點的樹。 

語義分析:  

編譯器所能分析的語義是靜態語義,所謂靜態語義是指在編譯期間可以確定的語義,與之相對應的動態語義,就是在執行期才能確定的語義。 

函式訪問必須知道目標函式的位址,變數訪問也必須知道目標變數的位址,所以這兩種方式都可以歸結為一種方式,那就是模組間符號的引用。 

人們把每個源**模組獨立地編譯,然後按照需要將它們組裝起來,這個組裝模組的過程就是「鏈結」

鏈結的主要內容就是把各個模組之間相互引用的部分處理好,使得各個模組之間能夠正確銜接。

重定位發生在鏈結階段,如果乙個模組需要使用另乙個模組的變數或函式,編譯的時候先給這個變數或函式乙個特殊的位址,鏈結的時候再來確定實際位址。這個  位址修正的過程也叫做重定位,每個要被修正地方叫乙個重定位入口。

《程式設計師的自我修養》第二章學習筆記

第二章 編譯和鏈結 2.1被隱藏了的過程 我們知道,乙個程式由源 到可執行檔案往往由這幾步構成 預處理 prepressing 編譯 compilation 彙編 assembly 鏈結 linking 如圖所示,2.1.1預編譯 includeint main void 如上述檔案hello.c,...

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

以下是我讀此書時作的一些筆記,當然書中還有很多值得參考的想法,就不一一枚舉了。一萬小時說法 這個說法很普遍了,它再次提醒了我如何去做乙個領域的專家。如果平均每天八小時在這個領域上,那麼一年300天 300 8 2400,保持這種學習激情在上面,五年內就可以成為專家了,我算了算自己在這個領域投入的時間...

程式設計師的自我修養

一忌 輕易言敗,沒有自信 沒有永不放棄精神的程式設計師,只是乙個有程式設計師名號的假程式設計師。乙個真正的程式設計師,知道在程式設計的過程中,可能會遇到不計其數的困難和問題,可能有極多的挫折和失敗,而成功只有一次。就為解決乙個問題,我們可能連續十幾甚至幾十小時的坐在計算機前不停的工作。乙個問題解決了...