對編譯連線過程的認識

2021-09-25 18:22:27 字數 2866 閱讀 7773

一.為何要有編譯連線的過程

原因:程式檔案需要執行環境,機器不識別高階語言

linux下可執行檔案是elf、windows下可執行檔案是pe

編譯連線過程:

預編譯 生成.i檔案

1.刪除#idefine 文字替換

2.#if #endif #elif

3.#include 展開標頭檔案

4.新增行號和檔案標識 用於編譯器產生除錯用的行號資訊及用於產生編譯錯誤和警告顯示行號

5.不處理#pragma

編譯 生成.s檔案

1.詞法分析

2.語法分析

3.語義分析

4.**優化volatile關鍵字禁止**優化,多執行緒中會出現問題

5.生成彙編指令

彙編 生成.o檔案

1.翻譯指令

彙編完成後遺留的問題

1.強弱符號(僅存在於c語言) 初始化和未初始化

2.符號表 外部符號

3.指令段 虛假的位址和偏移(此時還沒有完成位址對映所以分配的是虛擬位址)

鏈結 生成.exe檔案

1.合併段和符號 在鏈結之前都是在單個原始檔,整個專案是多個原始檔,將多個原始檔內容合併

2.符號解析

3.分配位址和空間

4.符號的重定位 原本的位址為虛擬位址,現在合併後將真實的符號位址賦予

程式經過編譯鏈結還是不可以執行,最終執行的是程序

鏈結前的檔案虛擬位址都為0

程式載入到記憶體執行過程:

程式 - 虛擬空間 - 記憶體 - (暫存器or快取) - cpu

1.首先建立核心對映結構體並建立虛擬位址空間和物理記憶體的對映

2.載入指令和資料

3.把入口位址寫入下一行指令暫存器

q:為何不將程式直接載入到記憶體中呢?

zone_dma 直接記憶體訪問區,不經過暫存器

zone_normal 與頁面的對映關係

zone_highmem 大於1g檔案的對映

問題:

以上的變數存放在何處?

.data(資料段)

gdata1 全域性變數並且已經初始化

gdata4 靜態全域性變數且已經初始化

data1 靜態區域性變數且已經初始化

.bss:

gdata2 全域性變數但初始化為0

gdata3 全域性變數但未初始化 無法區分強弱符號 故在符號表中標記為com*(弱符號)*

gdata5 靜態全域性變數初始化為0

gdata6 靜態全域性變數但未初始化

data2 靜態區域性變數初始化為0

data3 靜態區域性變數但未初始化

.text(指令段)

data4 區域性變數已經初始化

data5 區域性變數初始化為0

data6 區域性變數未初始化

包括函式符號

對於.bss段解釋:為未初始化的全域性變數和靜態區域性變數預留位置,它並沒有內容,所以也不佔據空間。

為何不將.data段和.text段合併呢?

1.當程式被裝載後,資料和指令分別對映到虛擬記憶體上,但是資料區域是可讀、可寫的,指令段僅僅是可讀,這樣操作可以限制程式的指令的更改。

2.考慮到cpu的快取,快取會提公升cpu與記憶體的資料交換,所以盡可能讓快取的命中率提高,當資料段和指令段分開後形成指令快取、資料快取,快取的命中率也就提公升了。

3.共享指令,當系統中執行多個程式的副本,它們的指令都是一樣的,那麼記憶體中僅須儲存乙份程式的指令部分。

函式的開棧

1.壓入實參 自右向左

2.壓入下一行指令的位址

3.壓入呼叫方函式的棧底指標暫存器的值

4.跳轉到被呼叫方函式棧幀

5.被呼叫方開闢區域性變數活動的空間並初始化cccc cccc

函式的返回值

<=4 eax暫存器帶回

<=8 >4 兩個暫存器 eax、edx

>8 臨時量

函式過載

釋義:同一介面 不同形態

bool compare(int, int)(1)

bool compare(double, double)(2)

c語言下生成的函式符號

_compare(1)

_compare(2)

c++下生成的函式符號

函式原型:函式的返回值 函式名 形參

不能作為函式過載依據

形參:1.個數2.型別3.順序

過載發生條件:同一作用域下,函式名一致,形參列表不同

呼叫過載函式的三種可能:

編譯器找到乙個與實參最佳匹配的函式,生成呼叫函式的**。

找不到任何乙個函式與呼叫的實參匹配,編譯器發處無匹配的錯誤資訊

多個函式匹配,但無最佳匹配,發生錯誤,(二義性呼叫)

U Boot的配置 編譯 連線過程

u boot,全稱為universal boot loader,即通用bootloader。通用有兩層含義 可以引導多種作業系統 支援多種架構的cpu。根據u boot原始碼資料夾頂層的readme檔案說明,針對使用的開發板 board 執行 1 make config 2 make all 可以生...

編譯鏈結過程

在談編譯鏈結過程之前我們需要了解一下虛擬位址空間以及程式在編譯鏈結過程時經過了什麼步驟。虛擬位址空間之前在程序空間的部落格中詳細介紹過了,詳見 上圖就是32位系統中4g虛擬位址空間的分布情況 text 段 指令段,存放的是指令 在程式中,我們把區域性變數定義 區域性變數的 定義是指令而不是資料 還有...

TCP連線過程

1 建立連線協議 三次握手 1 客戶端傳送乙個帶syn標誌的tcp報文到伺服器。這是三次握手過程中的報文1.2 伺服器端回應客戶端的,這是三次握手中的第2個報文,這個報文同時帶ack標誌和syn標誌。因此它表示對剛才客戶端syn報文的回應 同時又標誌syn給客戶端,詢問客戶端是否準備好進行資料通訊。...