1. 程式人生 > >c/c++編譯原理淺談(一)

c/c++編譯原理淺談(一)

-------------前言

渾渾噩噩就看完了一遍《高階c/c++編譯技術》,我知道看完一遍是不行,而且光是看也是不行的,先寫下這篇博文也權當是記錄下我的一些猜想,當然是未經過驗證的,經過驗證就不是猜想了。最終,在下有什麼說得不對的,請各位大俠指正,不斷學習不斷進步!

-------------正文

先說一下這本書。這本書是由Milan Stevanovic大佬寫的,盧譽聲所譯。結構內容是硬體基礎,程式的生命週期,生命週期中的各個階段的介紹,各類問題的解決。

第一章講解的是他的硬體支援,因為最終編譯是要編譯成機器能夠讀懂的二進位制語言,所以首先我們先要知道我們的目的是什麼,高階語言c/c++----------》某種工具(先把他當成一個黑箱)-------------》二進位制檔案。那麼,機器能夠讀懂的二進位制語言是需要到專用的晶片的指令,更重要的是指令的地址怎麼得到,怎麼做才能得到我們的二進位制檔案,怎麼做才能解決我們問題。這就是我大概能讀懂的意思,我還沒看過作業系統,一些更深的東西還沒看懂。

總結起來就是,最終我們要控制的是我們的I/O裝置,主存釋放位元組流,作為與IO進行資料交換的直接港口,主存被要求速度必須快,但是受成本問題,往往越大越貴,所以有一種快取機制,一個折中的方法。快取往往有多級,接近IO的越快,接近cpu的慢,這種分級制度在某種程度上起到了緩衝的作用,但是不可避免的,當IO資料量很大的時候,主存往往會請求硬碟幫忙,這就使虛擬記憶體的機制,這時就會顯得很卡。它使得應用程式認為它擁有連續的可用的記憶體(一個連續完整的地址空間),而實際上,它通常是被分隔成多個實體記憶體碎片,還有部分暫時儲存在外部磁碟儲存器上,在需要時進行資料交換。

怎麼做到讓它看起來是連續的呢?

實際上實體地址是不連續的,而是給實體地址的編號是連續的,在學數位電路和微機原理的時候,會教到一個就是給ram分配地址,按照事先約定好的規則,可以使它的地址號讀取是連續的。比如說奇偶地址位的讀取來滿足cpu的設定,intel8086的cpu有一個管腳說明是奇偶讀取地址,為了滿足的它的整體的一個架構,ram和譯碼器什麼的組合起來讓cpu看上去真的是在讀奇偶地址的。再詳細的只能去再查課本了。

程式的生命週期有:

編譯,連結,兩個階段,經過這兩個階段:

c/c++--------->編譯---------->彙編程式---------->連結--------------->二進位制檔案

二進位制檔案------------->裝載----------------->賦予絕對地址(可定址),執行

ok,我們一步步來介紹。

編譯:

1.執行單元:編譯器

2.輸入:編譯單元(通常為包含原始碼的文字)

3.輸出:一系列的二進位制目標檔案的集合

注意:此時的輸出雖然是二進位制檔案,但是是每個原始檔對應的目標檔案,也就是他們之間的聯絡還沒有連線起來。

ok,要成以上的輸入變成輸出,編譯器到底做了什麼事情呢?

1.預處理階段

輸入:c/c++

輸出:c/c++

使用一個特殊的文字處理程式,將巨集進行替換。將include關鍵字標識的含有特定檔案包含到原始碼檔案中,將define語句指定的值轉換成常量,將ifndef或ifdef、eleif和endif做相應的處理。

2.語言分析階段

輸入:c/c++

輸出:c/c++

最終得到一個精簡的、符合語法、語義的程式碼。有以下的幾個方面的過程:

      1.詞法分析:將原始碼分割成不可分割的單詞

      2.語法分析:將提出的單詞連成序列,並根據程式語言規則進行檢查,驗證其順序是否合理。

      3.語義分析:目的是發現符合語法規定的語句是否具有實際意義。

3.彙編過程

輸入:c/c++

輸出:彙編程式碼

轉換成特定cpu指令集的語言集合。經過1、2這兩個步驟,可以保證現在的c/c++程式碼是精簡有意義的存在了。那麼就可以把它轉換成彙編程式碼了。以gcc編譯器為例:

原始碼------------->gcc---------------->ASCII編碼的文字檔案

x86處理器體系結構的支援兩種指令格式:AT&T   intel  格式

4.優化階段

輸入:彙編程式碼

輸出:彙編程式碼

最初版本的彙編程式碼--------------------->優化-------------------------->最終版彙編程式碼

優化的原則:

         1.將暫存器使用率最小化

         2.通過分析能夠預測出實際上不需要執行的部分程式碼

5.程式碼生成階段

輸入:彙編程式碼

輸出:多個二進位制檔案集合

每一個目標檔案對應一個編譯單元,彙編指令轉成成對應的機器指令(操作碼)的二進位制值。

ok,這個編譯就完成了,再Linux上面,我們可以通過命令

gcc -S <input file> -o <output assembler file>.s                        //輸出彙編程式碼

寫的一個簡單的hello程式。

gcc -S -masm=intel hello.c -o hello.s


這就是彙編程式了,但是我彙編還沒看過,不怎麼懂,所以就不做分析了。知道是可以得出彙編程式的。

gcc -c hello.c -o hello.o

就得到了hello.o也即二進位制檔案,雖然你看著只有一個,但是別忘了你在剛開始學習得時候就不明白的為什麼要include一個什麼鬼東西呢,那個鬼東西在哪呢?那個東西就是共享庫,之後會介紹到,現在先不談。

所以,咱們通過這個命令就可以得到了二進位制目標檔案了,但是我們要檢視的話需要十六進位制的檔案檢視器,我沒有,直接用vim是一堆亂碼就不截圖了。

至此,編譯過程結束。往後請看下一節。

相關推薦

c/c++編譯原理

-------------前言渾渾噩噩就看完了一遍《高階c/c++編譯技術》,我知道看完一遍是不行,而且光是看也是不行的,先寫下這篇博文也權當是記錄下我的一些猜想,當然是未經過驗證的,經過驗證就不是猜想了。最終,在下有什麼說得不對的,請各位大俠指正,不斷學習不斷進步!----

線程

nds 創建 內存空間 線程 淺談 read 系統 多核 void 線程: 1相關的概念:   進程中包含一個或多個線程。   進程:運行再系統之上的一個程序實體,具有獨立的存儲空間。   線程:運行再進程裏面的一個子任務,沒有獨立的內存空間,必須共享新車的內存空間。   

H5鬥地主×××開發

日誌服務器 登錄 serve server lds 因此 的人 意義 運營 h5鬥地主遊戲開發Q1446595067 官網:h5.haozibbs.com去年從傳統軟件公司辭職,下定決心轉互聯網,由於對遊戲的熱愛,去了一家遊戲公司,待了將近10個月,參與開發了一款動作卡牌手

Office 365 SharePoint 遷移 開篇介紹

SharePoint O365 Office 365 Migration 遷移 今天再來開一個新的篇章,簡單來談談SharePoint到SharePoint Online的遷移,說實話這真是個相當大的話題,Office 365的遷移其實之前也談過一些了,但是基本上都是在談Excha

編譯原理學習筆記

.com bubuko image img 記錄 mage 學習 內容 基礎 簡單地瀏覽了一下第一章,主要是基礎性內容,就不記錄了。編譯原理學習筆記(一)

CTF之知識補充:網路基礎

開始做CTF題目的時候發現有太多的知識需要補救了,接下來就講講網路的一些基礎知識。因為是自學,肯定會不全面,大家看看就行,有不同見解的也可以在下方評論。 計算機網路體系結構的形成 在此之前,人們已經提出並設計出了計算機體系結構,從系統的角度去定義計算機的構成和

Android 快取 LruCache

    Android應用開發好多場景都是手機和web伺服器之間進行通訊,從服務端需要獲取資料,但是當訪問的資料比較大,比較多,並且是重複資料時,會極大影響效能,甚至應用崩潰,手機卡死,這時候就要考慮快取機制了!Android中可通過快取來減少頻繁的網路操作,減少流量、提升

嵌入式視覺

       最近閒來無事,吃雞之餘折騰了幾天樹莓派,在跑過幾次影象識別等Demo之後頓時對嵌入式機器視覺產生濃厚的興趣。趁現在有時間調研了一下嵌入式視覺的發展歷程,在這裡簡單記錄一下自己這幾天的探索。

編譯原理學習筆記制導翻譯器

《編譯原理》在第二章中給出了一個翻譯表示式的例子(從中綴表示式到字尾表示式)。總結了如下內容: 1. 寫出描述語法規則的產生式(文法包含產生式集合與符號集合) 2. 根據文法建立對應語句的語法分析樹 3. 消除語言的二義性 4. 運算子的結合性以及優先順

遊戲服務端開發

去年從傳統軟體公司辭職,下定決心轉網際網路,由於對遊戲的熱愛,去了一家遊戲公司,待了將近10個月,參與開發了一款動作卡牌手遊,遊戲最終也上線了。最近抽空寫寫過去對遊戲後端的一些感想吧。最近又去另外一家遊戲公司,參與開發一款MMO手遊。準備開始從動作卡牌手遊談到MMO手遊,也

伊始--C++程式設計師進階歷程

最近看了一篇《回答阿里社招面試如何準備,順便談談對於Java程式猿學習當中各個階段的建議》,心中有一些感觸。 在看這篇文章前幾周,還挺迷茫的。不知不覺也工作了很久,雖然在上班期間,每天或多或少地都在寫程式碼,但是很多都是僅僅增加熟練度,或者說是將別人現有的

c語言-樹的基礎知識

相交 ges 最大 .cn nbsp 分享 blog com lin 第一、樹的定義: 1.有且只有一個稱為根的節點 2.有若幹個互不相交的子樹,這些子樹本身也是一顆樹 第二、專業術語: 樹的深度:從根節點到最低層,節點的層數 ,稱之為樹的深度。

c#串口通信講解winform、wpf

定義 cep 回調 true comm ive get exc pre 串口操作需要註意的幾點如下: 1、如果是USB轉串口;則需要安裝USB轉串口驅動,附件有此驅動。 2、串口打開狀態最好不要直接插拔串口,可能會導致中控板或者串口線燒壞。 3、使用串口調試工具CEIWEI

構建用於C#應用程序的應用商店

開發工具 曾經 我只 info 代碼 bsp 環境 管理員 winform 我在就職的公司開發工具型軟件,桌面版的,我們公司有各種工具軟件的需求。現在我已經記不清我生產了多少了。我相信再過一段時間,也許幾個月,也許一年後,我也會記不住之前開發過什麽,或許有一定的類別的印象,

c語言數據類型

32位 9.png 溢出 ima con string sign unsigned 負數 (強數據類型) 1.常量   常量是程序中不可變的量   10為常量      兩種常量   #define 定義宏常量   const      #對於#define 類型的常量,c

C#導入導出Excel

bject gpo tel collect lean type close 表格 excel導入 C#操作Excel導入導出方法一,根據項目要求,對Excel操作有多重方法,有的是類庫自己編程設計格式,有的是JS根據表格的格式樣式直接導出。 現在介紹的是直接下載型: 根據

深度探索C++對象模型讀書筆記

復雜 理解 image play 基礎上 isp 靜態 布局 bject 《深度探索C++對象模型》這本書也算是學習C++面向對象編程的必備書了,打算花上幾天先簡單的看一遍,這種書看上好幾遍也不一定能理解太多,慢慢積累一點一滴吃透就好。下面把我看書過程中覺得比較有意義的摘錄

C# 異步編程學習

apm 結果 mic public b- num row worker inf 異步 編程 可在 等待 某個 任務 完成時, 避免 線程 的 占用, 但要 想 正確地 實現 編程, 仍然 十分 傷腦筋。 . NET Framework 中, 有三種 不同 的 模型 來 簡化

C陷阱與缺陷讀書筆記

之間 之前 符號 雙引號 陷阱 數組 調用 筆記 如果 第一章 1.2 按位運算符:& 邏輯運算符:&& 1.3 單字符符號:只有一個字符長 多字符符號:含多個字符

Python C AP的使用詳解

nds 項目 namespace 以及 int float 數據大小 mem else 簡介 介紹一下Python虛擬機的初始化及退出,Python基本數據類型的對象創建以及C和Python之間的數據類型互相轉換。 Python虛擬機的初始化及退出 初始化Python虛擬機