預編譯.i
刪除#define 文字替換
處理#include 遞迴展開
處理#if #end if等預編譯指令
刪除注釋
新增行號和檔案標識
保留#pragma
編譯.s
1.詞法分析
2.語法分析
3.語義分析
4.**優化
5.生成彙編指令(低階語言)
以下是彙編指令的**
int
main()
彙編.o
翻譯指令(把低階語言翻譯成機器語言)
.o稱之為目標檔案或者是可重入的二進位制檔案
彙編過程中 執行之前所有程式都在檔案中,執行後在記憶體中
檔案中沒有棧和堆的概念,預編譯 編譯 彙編 鏈結 程式都在檔案中。
我們來看乙個簡單**
#include
int gdata1 =10;
//全域性變數生成的都是資料 在.data
int gdata2 =0;
//.bss
int gdata3;
// .o中在*com*中存放
static
int gdata4 =20;
//.data也屬於資料
static
int gdata5 =0;
//.bss
static
int gdata6;
//.bss
intmain()
//函式名生成指令 指令段只有.text
解釋一下資料段有兩種
.data:存放已初始化且初始化不為0的資料
.bss:未初始化或初始化為0的資料
總結一下:全域性變數 和 靜態全域性變數 靜態區域性變數都生成的是資料。
普通區域性變數 生成的是指令,不會生成符號。
檔案標識main.c和段資訊.text .data .bss、資料gdata1 gdara2、函式會生成符號。
.o彙編後檔案中存在什麼內容?
elf格式的檔案 檔案布局為efl header(檔案頭部) .text(指令段) .data (資料段).comment(注釋資訊段) 最後為堆疊提示段。
然而bss檔案不存在,bss段的資訊從哪來?
要看section headers相當於看一下書的目錄
鏈結.exe
1.合併段和符號表(處理強弱符號)
2.符號解析(外部符號處理)
3.分配位址和空間
4.符號的重定位
鏈結階段百分之80以上的錯誤都發生在符號解析過程中
符號解析錯誤**
#include
intsum
(int
,int);
//sum函式只有引用的地方沒有定義的地方
intmain()
執行
1.建立虛擬位址空間和物理記憶體的對映(建立核心對映結構體)
pcb (程序控制塊)要先建立好然後裡面放虛擬位址空間和物理記憶體對映,然後建立頁目錄頁表
2.載入指令和資料
3.把程式的入口位址放到下一行指令暫存器
編譯鏈結執行原理 編譯鏈結執行過程
乙個.c cpp源程式檔案要最後變成.exe windows 或者.out linux 可執行檔案,要經過編譯和鏈結過程。四個步驟 預編譯,編譯,彙編,連線 一 預編譯 處理以 開頭的預編譯指令,比如 include,define等,規則如下 1 刪除所有的 define,並展開所有的巨集替換 文字...
C 編譯鏈結執行原理
1.預編譯 生成.i檔案 1.將所有的 define 刪除,並且展開所有巨集 2.處理掉所有條件預編譯指令,如 if ifdef elif else endif 3.處理 include 指令,這是乙個遞迴過程 4.刪除所有的注釋 和 5.新增行號和檔名標識 6.保留所有的 pragma編譯器指令,...
編譯鏈結執行原理 函式堆疊呼叫
首先先提出下面五個問題 1 形參開闢記憶體嗎?由誰開闢?2 形參的入棧順序?3 返回值如何帶出?4 被呼叫方結束後如何知道回退到呼叫方棧幀上?5 函式呼叫完成如何知道執行下一行指令?要解決這些問題,我們就要從彙編的角度切入。通過彙編 能夠使我們更加清晰地掌握函式的堆疊呼叫。彙編分為兩種形式inter...