1. 程式人生 > >“Hello World”的執行過程(編譯過程)

“Hello World”的執行過程(編譯過程)

之前對於編譯過程也是模稜兩可,具體的還真沒刻意瞭解過,最近看《深入瞭解計算機作業系統》第一章就講到了編譯過程,看完之後才終於徹底瞭解了一些。

#include<stdio.h>
int main()
{
	printf("Hellow world");
}

   程式生命週期是從一個“原始檔”開始的,程式設計師寫到文字並儲存,檔名***.c.源程式實際上是由0和1組成的位。這些位8個一組,稱為位元組。每一個位元組表示程式中的某個字元。例如第一個位元組的整數值是35,對應的字元是“#”,第二個字元對應的是105對應i,依次類推。只由ASCII字元組成的檔案稱為文字檔案,其他的是二進位制檔案!

為了能讓機器讀懂我們語言,所以需要進行一系列的轉換,轉換為機器能讀懂的低階語言指令,然後這些指令按照一種稱為可執行目標程式的格式打包好,以二進位制磁碟檔案形式存放起來,目標程式也稱為可執行程式,

從原始檔到目標檔案的轉換是由編譯器驅動程式完成的。

分為以下幾個階段:

預處理階段:前處理器根據以字元#開頭的命令修改原始的C程式,比如hello.c中第一行#include<stdio.h>指令告訴前處理器讀取系統檔案stdio.h裡面的內容,並把它直接插入到程式文本里面,得到另外一個C程式,通常以.i作為副檔名。

除此之外預處理階段還做一下事情:

1.進行巨集替換過程,比如define指令定義的內容(只是簡單的替換)。(const只在編譯執行時才會檢查)

2.刪除掉註釋的亂七八糟。

編譯階段:將hello.i翻譯成了文字檔案hello.s,包含一個組合語言程式。組合語言程式中每條語句都以標準的文字格式確切描述了一條低階機器語言指令。組合語言很有用,因為不同高階語言最後都轉換為通用匯編語言了。主要是進行了語法檢查,語義分析,並將程式碼翻譯成了組合語言。

彙編階段:彙編階段是將hello.s翻譯成了機器語言,可重定位的的目標檔案,儲存在hello.o中,它是一個二進位制檔案,位元組編碼是機器語言指令,而不是字元。如果在編譯器裡面開啟的話將是一串亂碼。

連結階段:這個階段主要是將靜態庫和動態庫連結,打包到一起稱為可執行檔案。比如printf存在於一個pintf.o程式中,連結器就負責他們的連結,合併為一個可執行檔案。

為什麼要了解編譯原理?(我接觸到還不知道要什麼時候==||)

1.優化程式效能:比如:switch比if else高效的多嗎?一個函式呼叫的代價有多大?為何兩個功能相似的運算函式效能相差很大?

2.理解連結時出現的錯誤:比如:連結器報告無法解析引用是什麼意思,?靜態變數全域性變數區別?靜態庫動態庫區別是什麼?

3.避免安全漏洞。