1. 程式人生 > >程式設計師的自我修養總結(一)

程式設計師的自我修養總結(一)

第二章 編譯和連結

1.        gcc hello.c

./a.out

預處理——編譯——彙編——連結

2.    預處理:預編譯 gcc –E hello.c –o hello.i或者hello.c >hello.i

原始檔和標頭檔案被預編譯器cpp編譯成.ii(c++)    .i(c)檔案,預編譯處理規則:

[1]      將#define刪除,展開所有巨集定義

[2]      處理所有條件預編譯指令,比如“#if”,“#ifndef”,“endif”,“else”

[3]      處理“#include”預編譯指令,將包含的檔案插入到預編譯指令的位置

[4]      刪除所有的註釋“//”“/****/”

[5]      新增行號和檔名標識,比如#2“hello.c”2,便於編譯時報錯警告便以其產生條使用的行號資訊

[6]      保留所有的#pragma編譯器指令

3.    編譯:gcc  –S hello.i  -o hello.s

編譯就是把預處理完的檔案進行一系列的詞法分析、語法分析、語義分析及優化後生產相應的彙編程式碼檔案。預編譯和編譯合併成一個cc1的程式

4.    彙編ashello.s –o hello.o或者gcc –c hello.s –o hello.o

將彙編程式碼轉變成及其可移植性的指令。

直接從原始檔開始經過預編譯、編譯和彙編生成目標檔案:gcc  -c hello.c –o hello.o

5.    連結

一個生成的可執行檔案包含很多目標.o檔案。包括地址和空間分配、符號決議(地址繫結)和重定位等步驟。就是把目標檔案和庫函式連結起來,最常見的庫是runtime library即執行時庫。

6.    編譯器的工作

[1]      詞法分析:掃描程式,產生一些記號:關鍵字、標示符、字面量和特殊符號

[2]      語法分析:將掃描器產生的記號生成以表示式為節點的語法樹

[3]      語義分析:主要是靜態語義,包括生命和型別的匹配,轉換。經過語義分析,語法樹的表示式被標識了型別,(有的要隱式轉換)

7.        中間語言生成

原始碼級優化器,產生中間程式碼,程式碼生成器把中間程式碼轉換成目標機器程式碼,目的碼優化器對目的碼優化、選擇合適的定址方式等

第三章  目標檔案

8.         

[1]      程式碼段:程式碼、函式被放在數程式碼段.text或者.code

[2]      資料段:已初始化區域性靜態變數和全域性變數被放在資料段.data

[3]      未初始化的全域性和區域性靜態變數預設為0,放在.bss中,因為為0所以在.data中分配空間沒有必要。

[4]      只讀資料段:.rodata就是隻讀變數const和字串常量。

[5]       

9.        目標檔案包括一個檔案頭、描述了檔案屬性,如是否可執行、動態還是靜態、入口地址、等,檔案頭包括一個段表,記錄了各個段在檔案中的偏移和短的屬性。