Dex劍譜七絕-序章

前言:

之前一直想研究我們寫的一段字符串(代碼)到底是怎么編譯成可執(zhí)行文件的,到底怎么去解析?中間到底發(fā)生了哪些 ?最終的可執(zhí)行文件

到底是怎么去執(zhí)行的?之前看SandHook源碼的時候也提到了編譯優(yōu)化的知識點,但是一直也沒理解,或者說當我們想去魔改一份編譯器的時候,把一段 int a= 1+2;如果可以編譯成只有機器能看懂并且無法反編譯的事情也是一件很酷的事情

之前也是一直沒有時間去總結(jié),最近心血來潮,也是抽時間準備這系列文章,希望對此有想法的開發(fā)者在學習的過程中能減少一些彎路。

什么是編譯器:

這個東西做過軟件開發(fā)的過程中可能都會使用,但是他具體如何去工作的呢?

當我們拿到一份代碼源文件的時候首先要經(jīng)過幾個階段

源文件->前端編譯器->中端編譯器(優(yōu)化器)->后端編譯器->機器碼

機器碼也就是計算器最終可執(zhí)行的二進制文件,現(xiàn)在主要比較肯定的編譯器架構(gòu)是三段式編譯器,如下圖

image.png

前端編譯器(Frontend):

其輸入為源代碼,輸出為中間表示(Intermediate Representation),簡寫為IR,IR也被稱作中間代碼、中間語言)。IR沒有標準語法。各編譯器都可以自定義IR。比如LLVM就有LLVM IR,而Java字節(jié)碼也是一種IR。前端的工作主要是解析輸入的源碼,并對其進行 詞法分析語法分析、語義分析、生成對應(yīng)的IR等。

詞法分析:

詞法分析的目標是識別輸入字符流中的特定單詞,把輸入的字符串翻譯成編譯器能夠明白的語言

語法分析:

判斷我們寫的字符串是否含有語法錯誤,比如有未定義的變量,寫錯了的關(guān)鍵字。

語義分析

用來確認我們這行代碼到底想告訴計算機具體做什么?具體怎么去分配內(nèi)容,怎么去執(zhí)行和解析

前端編譯器主要會經(jīng)過以下五部分的處理:

Lexical Analyisis

Parsing

Semantic Analyisis

Optimization

Code Generation

中端編譯器(優(yōu)化器(Backend)):

優(yōu)化器的輸入是未優(yōu)化的IR,輸出是優(yōu)化后的IR。常用的優(yōu)化手段有循環(huán)優(yōu)化、常量傳播和折疊、無用代碼消除、方法內(nèi)聯(lián)優(yōu)化等。另外,優(yōu)化器在優(yōu)化階段的最后還要執(zhí)行一項非常重要的工作,即考慮如何分配物理寄存器。比如,IR中往往使用不限個數(shù)的虛擬寄存器,而目標機器的物理寄存器的個數(shù)卻是有限的。所以優(yōu)化器需要有一種方法來合理分配物理寄存器。而對那些不能保存在物理寄存器中的值,優(yōu)化器還需要生成將這些值存儲到內(nèi)存、從內(nèi)存中讀取它們的指令。

可以理解為主要是性能上的優(yōu)化

IR可以理解為一種中間語言,編譯器使用的一種語言,一種字節(jié)流。

后端編譯器(Backend):

其輸入為優(yōu)化后的IR,輸出為目標機器的機器碼。后端的主要功能是將IR翻譯成機器碼

為什么大眾會認可三段式編譯器架構(gòu)呢?

不同語言的開發(fā)者可以開發(fā)針對特定語言的前端模塊,比如C、C++、Fortran。這些前端模塊只要將對應(yīng)語言的源代碼轉(zhuǎn)換成IR即可。

·優(yōu)化器模塊的輸入是IR,輸出也是IR。這種設(shè)計的好處是擅長優(yōu)化的開發(fā)者可以將精力集中在如何優(yōu)化IR上,而不會被輸入的編程語言以及目標機器的特性所束縛。

·同理,開發(fā)者可為不同目標機器開發(fā)對應(yīng)的后端模塊。如圖6-2中針對X86、ARM和MIPS機器的后端模塊。

總體而言,三段式編譯器架構(gòu)的設(shè)計充分體現(xiàn)了“術(shù)業(yè)有專攻”的重要性和必要性。因為對難度如此之大的編譯器開發(fā)而言,很少有開發(fā)者能同時精通這三個模塊。通過將編譯器拆分成三個較為獨立的模塊,開發(fā)者就能集中精力于他們所擅長的部分,不斷去發(fā)展和完善它們。

image.png

LLVM

什么是LLVM?

LLVM是構(gòu)架編譯器(compiler)的框架系統(tǒng),以C++編寫而成,用于優(yōu)化以任意程序語言編寫的程序的編譯時間(compile-time)、鏈接時間(link-time)、運行時間(run-time)以及空閑時間(idle-time),對開發(fā)者保持開放,并兼容已有腳本。

LLVM計劃啟動于2000年,最初由美國UIUC大學的Chris Lattner博士主持開展。2006年Chris Lattner加盟Apple Inc.并致力于LLVM在Apple開發(fā)體系中的應(yīng)用。Apple也是LLVM計劃的主要資助者。

目前LLVM已經(jīng)被Apple、Microsoft、Google、Facebook等各大公司采用。

-----------------《來自百度百科》

趣聞: Chris Latter 本來只是想寫一個底層的虛擬機,這也是 LLVM 名字的由來, low level virtual machine ,跟 JavaJVM 虛擬機一樣,可是后來,llvm從來沒有被用作過虛擬機,哪怕 LLVM 的名氣已經(jīng)傳開了。所以人們決定仍然叫他 LLVM ,更多的時候只是當作“商標”一樣的感覺在使用,其實它跟虛擬機沒有半毛錢關(guān)系。

LLVM只是一個編譯器基礎(chǔ)架構(gòu)和編譯器開發(fā)庫

但是他不是一個全套的編譯器,因為不包含前段編譯器

在LLVM架構(gòu)上,搭配針對不同編程語言的前端就可以構(gòu)造相應(yīng)語言的編譯器。比如Clang搭配LLVM就構(gòu)成了C/C++編譯器。

比如:

clang+LLVM: clang是LLVM的前端,把各種源碼編譯處理;

clang-tools-extra :clang默認以外的認為不是很重要的工具;

llvm架構(gòu)

GCC(GNU編譯器套件)和Clang

Gcc是一款全套的編譯器,有一套自己的IR體系

LLVM也可以搭配GCC使用,只要將GCC的前端模塊和LLVM組合,就能得到一個性能比GCC還強大的編譯器

現(xiàn)在用Clang比較多,具體原因細節(jié)可參考,

https://www.baidu.com/link?url=87kysJCikx39E7a9lDGdwZv89unAr9wSKA7eRHT9puR884PANCudGdLMszURKfYfmQ5MmkEnly8Iwcm2HtUQ3K&wd=&eqid=f40a26d300089cfe000000036001363b

LLVM編譯工具鏈編譯流程

使用LLVM的對一門語言編譯的簡圖如下所示:

LLvm編譯流程圖

LLVM編譯一個源文件的過程:預處理 -> 詞法分析 -> Token -> 語法分析 -> AST -> 代碼生成 -> LLVM IR -> 優(yōu)化 -> 生成匯編代碼 -> Link -> 目標文件

完全需要我們手工,或者依靠其他工具如lex, yacc來做的事情,是從源代碼到token的詞法分析和從token到AST的語法分析;詞法分析的輸出是將源代碼解析成一個個的token。這些token就是有類型和值的一些小單元,比如是關(guān)鍵字,還是數(shù)字,還是標識符,從AST轉(zhuǎn)LLVM開始,LLVM就開始提供一系列的工具幫助我們快速開發(fā)。從IR(中間指令代碼)到DAG(有向無環(huán)圖)再到機器指令,針對常用的平臺,LLVM有完善的后端。也就是說,我們只要完成了到IR這一步,后面的工作我們就享有和Clang一樣的先進生產(chǎn)力了。

CodeGen負責將語法樹從頂至下遍歷,翻譯成LLVM IR,LLVM IR是Frontend的輸出,也是LLVM Backerend的輸入,橋接前后端。

Art虛擬機編譯簡介:

Dex在ART機內(nèi)部默認的執(zhí)行方式是解釋執(zhí)行,在不同的Android版本對Dex進行二次編譯

比如OAT或者7.0以上JIT和OAT的聯(lián)合編譯,在Art虛擬機內(nèi)部的編譯器只包括優(yōu)化器和后端,優(yōu)化器的輸入是dex字節(jié)碼,其輸出是ART定義的HInstruction。

ART虛擬機的后端支持X86、ARM、MIPS架構(gòu)的32位和64位平臺

[圖片上傳失敗...(image-efc70a-1610786999213)]

編譯優(yōu)化有很多方法,分別針對不同的優(yōu)化目標,比如圖6-3中的方法內(nèi)聯(lián)優(yōu)化,以及無用代碼消除優(yōu)化、常量折疊優(yōu)化等。

參考:

《深入理解Android:Java虛擬機ART》

http://www.itdecent.cn/p/1367dad95445

https://blog.csdn.net/feibabeibei_beibei/article/details/88073678

https://blog.csdn.net/yayaayaya123/article/details/83993041

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容