在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

編譯器把代碼轉化為機器碼的過程

xCb1_yikoulinux ? 來源:一口Linux ? 作者:一口Linux ? 2022-08-03 13:56 ? 次閱讀

編譯器,是把高級語言轉化為機器語言的工具軟件。

高級語言的代碼也是個文本字符串,所以編譯器的前端與sed、gawk、grep是差不多的,都是廣義上的字符串匹配

編譯器把代碼轉化為機器碼過程如下:

1,詞法分析

這是編譯器里最簡單的模塊

詞法分析,就是通過查看下一個字符來確定怎么把代碼字符串分割成一個個的語法詞匯

起始符、終止符,是詞法分析的主要概念。

intday =24 * 3600;

這行代碼的第1個詞是int,起始符是i,終止符是空格

在詞法分析時它是一個標志符,也就是字母、下劃線、數字組成的一個字符串,必須以字母或下劃線開頭。

在分析出int這個標志符之后,它后面的空格就沒用了,直接丟棄它。

第2個詞day也是一個標志符,起始符是d,終止符也是空格。

習慣把代碼寫得密集的人可能這么寫:int day=24*3600;

這時day的終止符是=,它同時還是下一個詞的起始符,在把day加入詞匯序列之后需要從=開始接著分析。

第3個詞是=,第4個詞是24,第5個詞是*,第6個詞是3600,第7個詞是分號;

在詞法分析時要把數字字符串24和3600轉化為整數24和3600,這兩個在程序里是不同的。

10進制、16進制、8進制、2進制、浮點數的支持,都是詞法分析時的任務。

另外,轉義字符串也要在這里支持。

'' 在源代碼里是字符串文本,包含著4個字符' 0 ',要轉義成單個字符0。

' ' ' ' ' '的處理和''一樣。

詞法分析還是很好寫的。

2,語法分析

這是編譯器前端最難寫的模塊,它需要把源代碼轉化成一棵描述整個程序結構的多叉樹

這個多叉樹叫做抽象語法樹(英文縮寫AST)。

類型、變量、運算符、函數定義、函數調用、if語句、for/while循環,都是這個這棵樹的一部分。

抽象語法樹的層次結構,與源代碼的結構是一樣的。

如果是這樣的源代碼的話:

int sum = 0;

for (int i = 0; i < 8; i++) {

if (i % 2 == 0)

sum += i;

}

那么語法樹是這樣的:

f24d7d2a-12df-11ed-ba43-dac502259ad0.jpg

語法樹

初始化語句sum = 0與后續的for循環是順序執行的,它們屬于同一個順序塊,在語法樹上有同一個父節點

for循環有4個子節點初始化表達式i = 0,條件i < 8,循環體if語句、更新表達式i++。

其中循環體又是個if語句,具有2個子節點:條件表達式i % 2 == 0,主體sum += i。

while循環的結構與for類似,只要去掉初始化表達式和更新表達式就行,只有2個節點。

把詞法分析之后的詞匯序列轉化成抽象語法樹時,常用的方法是有限自動機

也可以把代碼直接寫成遞歸函數調用,但是后續改起語法來就比較麻煩。

我一開始就是把scf的parse模塊寫成了遞歸函數調用,后來為了可以編輯語法,又自己做了個簡單的有限自動機。

3,語義分析

把語法樹遍歷一遍,檢查一下類型是否匹配,就是語義分析。

如果要支持面向對象的話,就可以在這里進行函數重載運算符重載

常量表達式也要在這里計算出來,int day = 24 *3600要轉化成day = 86400。

f26b1600-12df-11ed-ba43-dac502259ad0.jpg

常量表達式的計算

對語法樹進行遍歷時,不同的語法節點使用的處理函數不同的,這就是語義

符號=要當作賦值,符號+要當作加法,其他類似。

C語言里常見的函數調用,語法樹是這樣的:

int printf(const char* fmt, ...);

int main()

{

printf("hello world ");

}

函數調用也是一個運算符,具有一個單獨的語法節點,它的子節點都是它的參數

其中函數名也是一個參數,要轉化為對應的函數體的節點的指針

通過這個指針才可以找到函數的代碼,進行內聯優化(inline)

f28dd780-12df-11ed-ba43-dac502259ad0.jpg

函數調用和定義

如果要是調用的外部函數,只有聲明沒有實現,那就沒法內聯了。

4,中間代碼生成(三地址碼),從這里開始就是編譯器的后端了。

這一步也是對語法樹進行遍歷,把對應的表達式、函數、if語句、for循環都變成類似匯編的三地址碼。

上面那段for循環,這時會被變成如下的三地址碼序列:

assign sum, 0

assign i, 0

start: // for循環的開頭

cmp i, 8

jge end //條件不成立,則結束循環

assignt, i % 2 // t是編譯器生成的臨時變量

cmp t, 0

jne next

add sum, sum, i // 這行才是三地址碼

next: // 下一輪for循環

inc i // 循環變量+1

jmp start //跳轉回開頭,繼續循環

end:// for循環結束

到了這里,那個復雜的樹型結構已經變成線形結構了,可以按順序寫到一個文本文件里,這就是匯編代碼

到這里,編譯器就可以生成類似gcc -S的匯編代碼了。

5,中間代碼優化

這是編譯器后端的主要部分,屬于機器無關優化,這部分的優化是不依賴于CPU平臺的。

scf框架的這部分包含以下功能:

1)內聯函數,

2)有向無環圖DAG的生成,

3)帶二級指針參數的函數調用分析,

4)指針別名分析,也就是分析指針指向的變量,

5)活躍變量分析,

6)變量的加載保存分析,

7)需要自動內存管理的變量分析,

8)代碼流程圖的深度優先排序

9)自動內存管理代碼的添加,

10)基本塊內的優化,

11)循環分析,

會把一些變量盡量在循環的入口加載,在循環出口保存,減少循環內的內存讀寫。

沒有常量傳播的優化,哪天有空我把它添上

6,寄存器分配

使用圖的著色算法,之前的文章寫過。

7,指令選擇

直接寫在代碼里的,沒做龍書里提到的那個樹的覆蓋。

8,機器碼生成

根據intel x64的手冊編寫機器碼就行。

9,目標文件生成

也就是gcc -c 得到那個.o文件。

Linux上的elf文件是什么樣的就怎么寫,可以參考linux的man手冊里對elf的講解。

10,可執行文件的生成

這是連接器的功能,它把多個.o .a .so文件連接成一個可執行文件。

這一步的代碼在scf/elf目錄,有興趣的可以看看。

連接之后的文件就可以在shell命令行里運行了。

審核編輯:湯梓紅


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 機器碼
    +關注

    關注

    0

    文章

    12

    瀏覽量

    8315
  • 代碼
    +關注

    關注

    30

    文章

    4788

    瀏覽量

    68617
  • 編譯器
    +關注

    關注

    1

    文章

    1634

    瀏覽量

    49133

原文標題:編譯器的代碼架構

文章出處:【微信號:yikoulinux,微信公眾號:一口Linux】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    機器碼提取, 芯片破譯

    本帖最后由 北風凜冽 于 2012-6-28 16:12 編輯 小弟現在的項目是要從集成電路的芯片里面提取程序的二進制代碼出來,哪位大神能提供MSP430系列和RENESAS系列芯片內部機器碼提取的方法?跪求!!!! {:23:}
    發表于 06-28 15:55

    求助機器碼問題

    一段機器碼在兩種不同的單片機實現的功能一樣嗎?
    發表于 07-29 23:18

    如何將高級C語言編譯機器碼

    C編譯機器碼要通過預處理,編譯,匯編,鏈接四個步驟。這四個步驟由誰做的呢?答案是編譯器編譯器做的工作類似我們IC行業里面的綜合。在IC設
    發表于 06-01 16:53

    arm7和arm9采用的指令系統的機器碼應該是不同的吧

    菜鳥的問題:arm7和arm9采用的指令系統的機器碼應該是不同的吧?那么編譯器是怎么確定所采用的架構的?或者說我需要根據所采用的ARM芯片的不同而采用不同版本的編譯器嗎?
    發表于 10-27 16:17

    RealView編譯工具4.0版編譯器用戶指南

    ARM編譯器armcc是一個優化的C和C++編譯器,它將標準C和標準C++源代碼編譯成用于基于ARM架構的處理
    發表于 08-12 06:05

    C編譯器的設計文檔與源代碼

    C-編譯器的設計文檔與源代碼:本壓縮包包含了C-編譯器的設計文檔與源代碼,供學習參考。  整體框架. 3 詞法分析. 3᠙
    發表于 02-09 11:13 ?45次下載

    編譯器是如何工作的_編譯器的工作過程詳解

    隨著計算機的發展,編譯器已經發揮著十分重要的作用。本文主要介紹了編譯器的種類、編譯器的工作原理以及編譯器工作的具體操作過程及步驟詳解。
    發表于 12-19 12:54 ?1.6w次閱讀

    MPLAB? XC8 C編譯器的架構特性

    本視頻介紹了MPLAB? XC8 C編譯器的架構特性。該編譯器編譯過程不同于傳統的編譯器,采用了一種稱為"OCG(全知
    的頭像 發表于 05-23 12:47 ?6048次閱讀
    MPLAB? XC8 C<b class='flag-5'>編譯器</b>的架構特性

    如何對單片機的機器碼進行反編譯代碼免費下載

    應一個做硬件的同事的要求,他利用其他軟件可以得到十六進制的機器碼,希望做一個簡單的軟件,可以將機器碼編譯成匯編指令。本來網上應該有很多這方面的軟件。但他說這個很特別,找不到,于是給他做了一個小軟件現在將
    發表于 07-17 17:38 ?11次下載
    如何對單片機的<b class='flag-5'>機器碼</b>進行反<b class='flag-5'>編譯</b><b class='flag-5'>代碼</b>免費下載

    華為方舟編譯器將在今年8月正式開源

    4月份的P30系列國行發布會上,華為宣布了革命性的“方舟編譯器”,通過架構級優化,顯著提升性能,尤其是全程執行機器碼,高效運行應用,徹底解決安卓應用“邊解釋邊執行”造成的低效率。
    的頭像 發表于 06-26 09:28 ?2049次閱讀

    電腦機器碼怎么修改

    在搜狗瀏覽搜索欄輸入:修改機器碼軟件下載 。然后點擊進入根據個人愛好下載修改機器碼軟件。
    的頭像 發表于 08-09 15:35 ?5.9w次閱讀
    電腦<b class='flag-5'>機器碼</b>怎么修改

    CompCert編譯器目標代碼生成機制研究綜述

    對 Compcert編譯器目標代碼生成機制進行剖析,主要介紹其設計邏輯、翻譯過程、語義保持性以及代碼結構,并給出了 Compcert編譯器
    發表于 05-07 10:17 ?7次下載

    交叉編譯器安裝教程

    交叉編譯器中“交叉”的意思就是在一個架構上編譯另外一個架構的代碼,相當于兩種架構“交叉”起來了。Ubuntu 自帶的 gcc 編譯器是針對 X86 架構的,而我們現在要
    的頭像 發表于 09-29 09:12 ?3514次閱讀

    AI編譯器技術剖析

    隨著人工智能技術的飛速發展,AI編譯器作為一種新興的編譯技術逐漸進入人們的視野。AI編譯器不僅具備傳統編譯器的功能,如將高級語言編寫的源代碼
    的頭像 發表于 07-17 18:28 ?1639次閱讀

    Triton編譯器的優化技巧

    (Instruction Selection) Triton 編譯器在指令選擇階段采用了先進的算法來生成針對特定硬件架構優化的指令。這一階段的目標是將高級中間表示(IR)轉換為低級機器代碼,同時盡可能地利用硬件
    的頭像 發表于 12-25 09:09 ?181次閱讀
    主站蜘蛛池模板: 午夜精品久久久久久久四虎| 午夜黄色大片| 色多多在线观看视频| 成年人网站黄色| 奇米影视四色7777| 欧美亚洲专区| 欧美在线一级视频| 五月停停| 亚洲一区免费视频| 日韩三级毛片| 亚洲黄色录像| 又粗又长又爽又长黄免费视频| 特别毛片| 真实一级一级一片免费视频| 激情伦成人综合小说| 四虎在线精品| 午夜网站在线播放| 亚洲一区区| 欧美精品久久久久久久小说| 天天骑天天干| 狠狠gao| 久久精品亚洲一级毛片| 久久是精品| 一级做a爱过程免费视| 国模人体一区二区三区| 亚洲操综合| 三级黄色片免费观看| 天天操夜夜爽| 在线观看国产久青草| 国产1区2区三区不卡| 黄色在线网站| 欧美四级在线| 久久久久免费| 婷婷丁香九月| 天天做天天爽| 99久久99久久| 99国产精品农村一级毛片| 中文字幕一区视频| 女人张开腿男人桶| www.色黄| 欧美在线91|