【學習總結】05 | 鏈接器:符號是怎么綁定到地址上的?

1、前言

首先,我認為學習總結,要有所總,所結,就是有歸納后,能用自己的話告訴別人!有所結,就是有所收獲輸出,一般我認為是思維導圖,所以,每篇文章前,我都會先給出文章的腦圖:

iOS開發高手課-05-鏈接器:符號是怎么綁定到地址上的?.png

2、正文

注意,本系列總結不會引用或提供原課程文章所有的內容或代碼,只會作出思維導圖,需要學習可購買課程 《iOS開發高手課 - 極客時間》

鏈接器 對于剛剛接觸程序開發的同學可能基本不懂,雖然大學學習編譯原理計算機原理等。這些知識比較抽象,為了讓大家明白,我們需要站在巨人的肩膀上!所以,本文需要一個巨人 ----- 編譯器 來幫助大家理解 鏈接器 是什么?為什么?大家有沒有想過,你寫的代碼,最終是怎么樣在計算機或手機上運行的???那現在就讓我們來了解一下吧!

《程序是怎樣跑起來的》

“計算機組成原理”圖解趣味版,蹲馬桶就能看懂的編程基礎知識!普及計算機知識。如何向小學生講解CPU和二進制?如何向中學生講解內存和磁盤?如何向女高中生講解操作系統的原理?如何向老奶奶說明顯示器和電視的不同?

《程序是怎樣跑起來的》作者是日本矢澤久雄,我們需要解析 編譯器,所以需要簡單入門級的計算機組成原理,這本書就是這樣一本優秀的書!大家可能通過微信讀書讀到電子版: 程序是怎樣跑起來的 - 微信讀書,目前2020年微信還有很多無限卡會員的免費閱讀,當然如果必要花 19.99 元我認為也值得。好了我們就不多說了,下面我主要摘取書中幾個示意圖來解析 編譯器

程序運行流程示例

圖1-1-程序運行流程示例.jpg

上圖展示程序運行流程示例,從我們編寫的高級語言的代碼,到 CPU(Central Processing Unit,中央處理器)所負責的就是解釋和運行最終轉換成機器語言的程序內容,其實是 編譯器 工作的流程。

CPU的四個構成部分

圖1-2-CPU的四個構成部分.jpg

CPU 的內部由寄存器控制器運算器時鐘四個部分構成,各部分之間由電流信號相互連通。本文我們不關注 CPU 的工作原理,本圖主要是后面要解析代碼運行在不同 CPU 上,需要 編譯器 對不同的 CPU 做兼容和優化。為什么會有不同的 CPU,上圖就說明了,簡單來說寄存器、控制器、運算器和時鐘的設計和數量不同,那就是不同的 CPU,所以代碼在不同的 CPU 運行就可能有不一樣的要求,這是硬件方面。這里就不深入解析了,大家可以看看本書,或自行搜索了解更多。

CPU負責解析并運行從源代碼編譯而來的本地代碼

圖7-2-CPU負責解析并運行從源代碼編譯而來的本地代碼.jpg

CPU 只能解釋其自身固有的機器語言,機器語言的程序稱為本地代碼(native code)。不同的CPU能解釋的機器語言的種類也是不同的。例如,CPU有 x86MIPSSPARCPowerPCARM等幾種類型,它們各自的機器語言是完全不同的。

程序員用C語言等編寫的程序,在編寫階段僅僅是文本文件,文本文件(排除文字編碼的問題)在任何環境下都能顯示和編輯,我們稱之為源代碼。通過對源代碼進行編譯,就可以得到本地代碼。到目前,我們了解了代碼編譯的流程啦,那具體的流程又是怎么樣的呢?在講解之前,我們先看看 CPU 的歷史,這樣對我們了解編譯器也起到重要作用啊~

這里解析一下各種 CPU :

  • x86:美國 Intel (英特爾)的微處理器,是按照8086、80286、80386、80486、Pentium(奔騰)……這樣的順序不斷升級的。因為這些型號的后面都帶有86,所以總稱為x86。32位處理器 Intel官方文檔里面稱為“IA-32”,64位處理器稱“x86_64”、“x86-64”,又稱x64,即英文詞 64-bit extended,64位拓展的簡寫。這個64位有點故事,下面講。現在的PC機都是64位 CPU 啦。
  • MIPS:美國 MIPS 科技公司開發的CPU,曾出現過面向 MIPS工作站的 Windows,不過現在市面上已經不再出售了。
  • SPARC:美國 SUN系統開發的CPU,很多工作站都采用了該CPU。
  • PowerPC:是美國蘋果、IBM、摩托羅拉共同開發的CPU,蘋果的Power Mac及IBM的工作站都采用了該CPU,不過現在的Mac采用的是Intel的x86系列CPU。
  • ARM ARM,安謀控股公司(英語:ARM Holdings plc.),又稱ARM公司。ARM的前身為艾康電腦,1978年于英國劍橋創立。2016年7月18日,日本軟銀集團斥資3.3萬億日元(約合311億美元)收購了ARM公司。ARM架構版本從 ARMv3 到 ARMv7 支持32位,2011年發布的ARMv8-A 架構添加了對64位支持。現在移動設備主流就是使用 ARM 。
x86-64 的故事

x84_64x86 32位 CPU 開始邁向64位的時候,有2種選擇:

  1. 向下兼容x86。
  2. 完全重新設計指令集,不兼容x86。

結果在 1999 年 AMD 搶跑了!比 Intel 率先制造出了商用的兼容 x86 的CPU,AMD稱之為 AMD64,搶了64位PC的第一桶金,得到了用戶的認同。所以 Intel 為了面子就選擇了設計一種不兼容x86的全新64為指令集,稱之為IA-64(Itanium,安騰),但是比 AMD 晚了一步,因為 AMD64 能有效地把x86架構移至64位的環境,并且能兼容原有的x86應用程序。并且 IA-64 也挺慘淡的,因為是全新設計的CPU,沒有編譯器,也不支持 Windows(微軟把intel給忽悠了,承諾了會出對應的 Windows server 版,但是遲遲拿不出東西),處理器本身和軟件移植的成本難以控制,導致 IA-64 最終流產。后來不得不在時機落后的情況下也開始支持AMD64的指令集,但是換了個名字,叫x86_64,表示是 x86 指令集的64擴展,大概是不愿意承認這玩意是AMD設計出來的?現時英特爾稱之為“Intel 64”,在之前曾使用過“Clackamas Technology” (CT)、“IA-32e”及“EM64T”等名字。換湯不換藥,核心與 AMD64 幾乎相同,猶如一對孿生兄弟,其實都是 x86-64 架構。當年有媒體為 EM64T 起了“iAMD64”別名,諷刺 Intel 在迎擊 AMD 的民用64位技術上,使用了 AMD 的技術,直接把 AMD64 吸納過來,并以新名重新包裝使用,所以最后,Intel 索性將此技術正式命名為 Intel 64

所以,CPU 的 32 位還是 64位,一般是用 x86-64 表示64位,而32位現在已經沒有了。另外,不同公司對 x86-64 架構,名字上還是有一些區別,蘋果公司和RPM包管理員以“x86-64”或“x86_64”稱呼此64位架構。甲骨文公司及Microsoft稱之為“x64”,BSD家族及其他Linux發行版則使用“x64-64”,32位版本則稱為“i386”(或 i486/586/686),Arch Linux用x86_64稱呼此64位架構。

最后一個問題,x86、x86_64主要的區別是什么?就是32位和64位的問題,x86 中只有8個32位通用寄存器,分別是 eax,ebx,ecx,edx, ebp, esp, esi, edi。x86_64 把這8個通用寄存器擴展成了64位的,并且比x86增加了若干個寄存器(好像增加了8個,變成了總共16個通用寄存器)。譬如四個通用寄存器(RAX, RBX, RCX, RDX)是由32位的(EAX, EBX, ECX, EDX)64位擴展而來,相應的還有指針寄存器(RIP, RBP, RSP, RSI, RDI),以及增加八個通用寄存器(R8~R15)等等。 這些資源只可在x64處理器的64位模式下使用,在用來支持x86軟件的遺留模式和兼容模式中是不可見的。

以上內容和關于 CPU 更多歷史和資料,可查看來源: x86 - 維基百科x86-64 - 維基百科,自由的百科全書X86、X64和X86_64區別

轉換成本地代碼后就變成了同樣的語言

圖8-2-轉換成本地代碼后就變成了同樣的語言.jpg

前面提到,CPU 只能解釋其自身固有的機器語言,而轉換成機器語言的程序就是本地代碼。不管用那種編程語言編寫的源代碼,最后只要能翻譯(編譯)成本地代碼,那么 CPU 就能理解。這個過程,其實就是編譯器的工作內容!

同樣的源代碼可以轉換成適用于不同處理器的本地代碼

圖8-5-同樣的源代碼可以轉換成適用于不同處理器的本地代碼.jpg

根據 CPU 類型的不同,本地代碼的類型也不同。因而,編譯器不僅和編程語言的種類有關,和 CPU 的類型也是相關的。這就是前面為什么要重點說 CPU 相關知識,現在是不是有點理解編譯器了!

把C語言等高級編程語言編寫的源代碼轉換本地代碼的程序稱為編譯器,這個轉換過程經過語法解析、句法解析、語義解析等。每種編程語言編寫的源代碼都需要其專用的編譯器,或者是同用類編譯器,比如 C 家族(C/C++)的編輯器。

Windows中的編譯和鏈接機制

圖8-8-Windows中的編譯和鏈接機制.jpg

剛才說的高級編程語言的源代碼轉換本地代碼,本地文件是無法直接運行的,還需要把多個目標文件結合,生成1個可執行文件(圖中是EXE文件,針對Windows系統的。),這個處理就是鏈接,運行連接的程序就稱為鏈接器(linkage editor,或連結器)。至此,我們終于說到鏈接器啦!!!現在明白鏈接器是在那里使用了吧?

存儲著目標文件的實體,并直接和可執行文件結合的庫文件形式稱為靜態鏈接庫,經常簡稱為靜態庫。與之相反的,就叫動態鏈接庫(動態庫),就是參與鏈接過程,但是并不會與可執行文件結合,就是說鏈接時會做標記,綁定的地址在加載后再決定。這個不理解,沒關系,下面還會在詳細說說,下一章的內容就是動態鏈接庫動態鏈接器的內容,所以,這個需要了解一下。

至此,我們就過編譯器相關的內容,簡單的解說了一下,不知道大家有點理解沒有,下面,我們在深入一點,了解編譯器的具體工作流程。

編譯器

編譯器一般采用 Three-Phase(三階段/三相)架構設計:

  1. 編譯器前端(Front end)
  2. 中間端(Middle end,或叫優化器,Optimizer)
  3. 后端(Backend)

編譯器前端(Front end)

  1. Preprocess - 預處理
  2. Parser - 解析器
  3. Lexical Analysis - 詞法分析
  4. Semantic Analysis - 語義分析
  5. AST(Abstract Syntax Tree,抽象語法樹)
  6. Static Analysis - 靜態分析
  7. CodeGen - IR 代碼生成

編譯器前端的任務:預處理語法分析語義分析,在這個過程中,也會進行類型檢查,如果發現錯誤或者警告會標注出來在哪一行等,最終生成中間代碼 IR(Intermediate Representation,中間端表達式)。對于 LLVM 來說,前端就是 CLang

中間端(Middle end,或叫優化器,Optimizer)

  1. LLVM Bitcode - 生成字節碼
  2. Assemble - 生成Target相關匯編
  3. Assemble - 生成Target相關 Object(Mach-o)
  4. Link 生成 Executable 可執行文件

優化是非常重要的,很多直接轉換來的代碼是不合適且消耗內存的,因為是直接轉換,所以必然會有這樣的問題,而優化放在這一步的好處在于前端不需要考慮任何優化過程,減少了前端的開發工作。中間代碼要經過一系列的優化,優化用的是 Pass,中間代碼的優化也可以開發者自己編寫,可以插入一個 Pass

后端(Backend)

  • ARM(ARM,安謀控股公司)
  • x86|x86-64(Intel,英特爾)
  • PowerPC(Apple & IBM & Motorola,AIM聯盟)

編譯器后端會進行機器無關的代碼優化,生成機器語言,并且進行機器相關的代碼優化。對于 iOS 的編譯過程,后端的處理:LLVM優化器會進行BitCode的生成,鏈接期優化等,LLVM機器碼生成器會針對不同的架構,比如arm64等生成不同的機器碼。

這里的后端,最終就是生成對應的 CPU 能執行的機器語言,前面已經介紹過 CPU 相關的。

上面說了編譯器的組成架構和簡要的工作流程,詳細的工作流程這里就不多說了,因為已經有很多優秀的內容了,并且本文的主要目的是要說明編譯器是什么!你知道它是什么后,再了解它是怎么用,有什么優缺點,自然不是難事!以上的部分內容是針對 iOS 和 LLVM 的,所以,我們接下來就來介紹一下 LLVM 編譯器吧!

要講解 LLVM 前,有必要的說說 GCC(GNU Compiler Collection,GNU編譯器套件) ,因為蘋果最初也是使用 GCC,后來慢慢的替換為 LLVM 的。

GCC(GNU Compiler Collection,GNU編譯器套件)

原名:GNU C語言編譯器(GNU C Compiler),通常是跨平臺軟件的編譯器首選。(在所有平臺上都使用同一個前端處理程序,產生一樣的中間碼)。

但是由于以下問題,導致蘋果轉為 LLVM:

  • GCC 的 Objective-C Frontend 不給力
  • GCC 插件、工具、IDE的支持薄弱

GCC的前端不是蘋果提供維護的,想要添加一些語法提示等功能還得去求GCC的前端去做。 很多編譯器特性沒有,自動補全、代碼提示、warning、靜態分析等這些流程不是很給力,都是需要IDE調用底層命令完成的,結果需要以插件的形式暴露出來,這一塊GCC做的不是很好。

LLVM

早年Apple一直使用 GCC 作為官方的編譯器,但Apple對 GCC 的性能不滿意,再者 Objective-C 在 GCC 中優先級低,GCC 對 Objective-C 語言新特性的支持程度也不高。因此Apple一直在尋找compiler(編譯器)的開源替代品,于是他們將目光轉移到LLVM身上。

來自維基百科:關于LLVM這個名字的來源,LLVM的命名最早源自于底層虛擬機(Low Level Virtual Machine)的首字母縮寫,由于這個項目的范圍并不局限于創建一個虛擬機,這個縮寫導致了廣泛的疑惑。

LLVM 就是 LLVM, 并不是 Low Level Virtual Machine(底層虛擬機)的簡寫!現今LLVM 已單純成為一個品牌!根據官網說明:

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies. Despite its name, LLVM has little to do with traditional virtual machines. The name "LLVM" itself is not an acronym; it is the full name of the project.
LLVM項目是模塊化和可重用的編譯器及工具鏈技術的集合。盡管名稱如此,LLVM與傳統虛擬機關系不大。名稱“ LLVM”本身不是縮寫。它是項目的全名。

2000年,伊利諾伊大學厄巴納-香檳分校(University of Illinois at Urbana-Champaign 簡稱UIUC)這所享有世界聲望的一流公立研究型大學的 Chris Lattner(克里斯·拉特納,twitter @clattner_llvm ) 和 Vikram Adve(維克拉姆·艾夫)想要為所有靜態及動態語言創造出動態的編譯技術,而開發的編譯器開發工具套件。2005年,蘋果電腦雇用了 Chris Lattner 克里斯·拉特納及他的團隊為蘋果電腦開發應用程序系統,LLVM 涉及范圍越來越大,可以用于常規編譯器,JIT編譯器,匯編器,調試器,靜態分析工具等一系列跟編程語言相關的工作。Chris Lattner 后來又開發了 Clang,使得 LLVM 直接挑戰 GCC 的地位。

Chris Lattner 大神簡介

Chris Lattner 生于 1978 年,2005年加入蘋果,將蘋果使用的 GCC 全面轉為 LLVM。2010年開始主導開發 Swift 語言。2017年1月,克里斯·拉特納 辭去在蘋果的工作,入職特斯拉汽車,負責自動駕駛軟件的開發。2017年8月14日,克里斯·拉特納 發表Twitter表示將于一周后加入聚焦于深度學習與人工智能研發的Google Brain團隊。

Xcode 歷史

Clang 編譯效率是 GCC 的3倍,編譯器性能好,編譯出的文件小。LLVM 3.0 發布已完整支持所有 ISO C++ 標準,代表著 LLVM 正式走向成熟。所以,也標志著 Xcode 的變化。

  • Xcode3:GCC前端-LLVM后端,
  • Xcode4.2:Clang-LLVM 3.0 成為默認編譯器,
  • Xcode5: GCC 被廢棄,新的編譯器是 LLVM 5.0

從 GCC前端 到 LLVM后端的編譯器,到 Clang-LLVM 的編譯器,一步步收回對編譯工具鏈的控制,也為 Swift 的出現奠定基礎。所以,Chris Lattner 真的是大神!

LLVM 工具鏈

LLVM工具鏈集合.png

最后用這張圖來表示完整的LLVM工具鏈集合的六大執行單元。

  1. 詞法分析: 將源代碼中的所有字符切分成記號(Token)的序列。包括了詞法分析器、記號序列化生成器和掃描器,不過掃描器常常作為詞法分析器的第一階段。
  2. 語法分析: 分析符合一定語法規則的一串符號,它通常會生成一個抽象語法樹(AST - Abstract Syntax tree),用于表示記號之間的語法關系。
  3. 語義分析: 通過語法分析的解析后,這個過程將從源代碼中收集必要的語義信息,通常包括類型檢查、在使用之前確保聲明了變量等等。
  4. 中間代碼(IR)生成:代碼在這個階段會轉換為中間表示式(IR),這是一種中立的語言,與源語言(前端)和機器(后端)無關。
  5. 優化中間表達式:中間代碼常常會有冗余和死代碼的情況出現,而優化器可以處理這些問題以獲得更優異的性能。
  6. 生成目標代碼: 最后后端會生成在目標機器上運行的機器碼,我們也將其稱之為目標代碼。

鏈接器

  • 為什么要讓鏈接器做符號和地址綁定?不綁定的話,又會有什么問題?
  • 鏈接器為什么還要把項目中的多個 Mach-O 文件合并成一個。

回到本文開始的問題,大家對這2個問題心中有答案了嗎?

鏈接器的作用是將符號綁定到地址上,符號表是內存地址與函數名、文件名、行號的映射表。所以,變量、函數與地址綁定,CPU 才能理解解析代碼。而為什么要多個 Mach-O 文件合并一個最終的 Mach-O?過去面向過程編程時,可以寫一個文件中,而現在主流是面向對象,就有類與對象關系,所以一般是分類、分模塊、分空間來編寫源代碼,所以,需要把這些類與對象和他們之前調用關系綁定一起,合并成一個Mach-O。為了更好理解這個 Mach-O,需要了解 CPU 是怎么執行他們的,這里就不展開了,感興趣的同學可以先自行搜索了解更多。

觸類旁通

Clang/Swift-LLVM編譯器架構.png

讓我們再次回顧一下編譯器的工作流程,以 LLVM 為例,從 iOS 開發視角來看這個問題。這張圖片來源:從Swift橋接文件到Clang-LLVM - 掘金。詳細的編譯器過程大家可以參考文章,這里就不過多重復。

Clang-LLVM編譯過程.png

另外,原文還提到很多的概念,這里也不一一提出了,具體可以看看本文最前面的思維導圖。比如:

  • AST(Abstract Syntax Tree,抽象語法樹)
  • Mach-O:是 Mach Object 文件格式的縮寫,它是一種用于可執行文件,目標代碼,動態庫,內核轉儲的文件格式。作為a.out格式的替代,Mach-O提供了更強的擴展性,并提升了符號表中信息的訪問速度。
  • 符號表:是內存地址與函數名、文件名、行號的映射表。格式如:<起始地址> <結束地址> <函數> [<文件名:行號>]
  • dyld(the dynamic link editor):當加載 Mach-O 文件時,動態鏈接器會先檢查是否有共享緩存。每個進程都會在自己的地址空間映射這些共享緩存,這樣做可以起到優化App啟動速度的作用。
  • LLDB(LLVM項目的調試器組件)
  • ASLR (Address space layout randomization,地址空間配置隨機加載)
  • 解釋器:不需要經過編譯的過程,而是在執行的時候通過一個中間的解釋器將代碼解釋為CPU可以執行的代碼。JavaScript、Python、PHP等都是直譯式語言。
  • Bitcode:字節碼
  • SIL(Swift Intermediate Language):AST 和LLVM IR之間的另一種中間代碼表示形式。主要是用來彌補一些 Clang編譯器的缺陷,如無法執行一些高級分析,可靠的診斷和優化等。

中間代碼 LLVM IR

中間端表達式 IR(Intermediate Representation),有3種表示形式,但本質是等價的,就好比水可以有氣體,液體,固體3種形式。

  1. text:便于閱讀的文本格式,類似于匯編語言,拓展名.II。生成命令:$ clang -S -emit-llvm main.m
  2. memory:內存格式,開發時操作 LLVM IR。
  3. bitcode:二進制格式,拓展名.bc。生成命令:$ clang -c -emit-llvm main.m

廣義與狹義 LLVM 與 Clang 的關系

廣義 LLVM:整個 LLVM 架構。

狹義 LLVM:LLVM 后端(代碼優化,目標文件生成等。)

Clang(C Lange Family Frontend for LLVM),發音為/?kl??/,是C、C++、Objective-C、Objective-C++ 編程語言的編譯器前端。

所以,非特指,LLVM 就是廣義 LLVM,指整個LLVM項目,包括Clang前端。另外,本文主要講解了 LLVM 在 Apple 平臺上的使用,LLVM 現在被作為實現各種靜態和運行時編譯語言的通用基礎結構,可以使用 LLVM 來編譯Ruby,Python,Haskell,Java,D,PHP,Pure,Lua和許多其他語言。LLVM 的主要優勢在于其多功能性,靈活性和可重用性,這就是它被用于各種不同任務的原因:從輕量級JIT編譯嵌入式語言(如Lua)到編譯Fortran代碼(用于大型超級)電腦。

相比較GCC,Clang具有哪些優點

  • Clang是:
  • LLVM項目的一個子項目
  • 基于LLVM架構的 C、C++、Objective-C、Objective-C++ 編譯器前端
  • Clang優點:
  • 編譯速度快:在某些平臺上,Clang的編譯速度顯著的快過GCC
  • 占用內存小:Clang生成的AST(語法樹)所占用的內存是GCC的五分之一左右
  • 模塊化設計:Clang采用基于庫的模塊化設計,易于IDE集成及其他用途的重用
  • 診斷信息可讀性強:在編譯過程中,Clang創建并保存了大量詳細的元數據,有利于調試
  • 設計清晰簡單,容易理解,易于擴展增強

Swift 如何橋接 Objtive-C 文件到 Clang-LLVM ?

在 Swift 的項目中,Objtive-C 代碼可以生成 IR(Intermediate Representation,中間端表達式),從而與 Swift 生成的 IR 聯通。這個也是分段(層)的好處,編譯器中間端(Middle end,或叫優化器,Optimizer),作為中間者通過前端獲取 IR ,從而不用關心前端的編程語言是什么,這些設計特點,帶來了非常大的好處。

假如有N種語言(C、OC、C++、Swift...)的前端,同時也有M個架構(模擬器、arm64、x86...)的Target,是否就需要 N × M 個編譯器?
三相架構的價值就體現出來了,通過共享優化器的中轉,很好的解決了這個問題。
假如你需要增加一種語言,只需要增加一種前端;假如你需要增加一種處理器架構,也只需要增加一種后端,而其他的地方都不需要改動。這復用思想很牛逼吧。

來自:淺談iOS編譯過程 - 簡書

需要注意的是 Clang 是基于LLVM架構的 C、C++、Objective-C、Objective-C++ 編譯器前端,不包括 Swift!蘋果針對 Swift 做了單獨的前端,與 Clang 是非常相似的,特點就是增加了 SILSwift Intermediate Language)。詳細具體可以查看 WWDC 視頻:What's New in LLVM - WWDC 2016 - Videos - Apple DeveloperBehind the Scenes of the Xcode Build Process - WWDC 2018 - Videos - Apple Developer

方舟編譯器

方舟編譯器架構示意圖.png

當前方舟編譯器支持Java/Kotlin程序字節碼的前端輸入,其它編程語言的支持(如 C/C++/JS 等)還在規劃中,方舟編譯器的中間表示(IR)轉換器將前端輸入轉換成方舟IR,并輸送給后端的優化器,最終生成二進制文件,二進制文件與編譯器運行時庫文件鏈接生成可執行文件,在方舟的運行環境中就可執行該文件。

方舟編譯器IR是支持程序編譯和運行的中間程序表示。程序源代碼中的任何信息對于程序分析和優化都是有幫助的,所以方舟IR的目標是盡可能完整詳細地提供源程序的信息。

方舟編譯器開源范圍示意圖.png

首次開源范圍是編譯器 IR( Intermediate Representation)、RC(Reference Counting)和多語言設計思想等,用于與業界、學術界溝通交流。后續將陸續開源編譯器前端、后端,支持其它語言(如 JavaScript)的編譯等,當前部分Java語言特性和JVM虛擬機特性的支持未包括在本次開源代碼中,包括:annotation、lambda表達式、泛型等。目前仍有很多地方不完善,會在社區陸續迭代,遇到問題請在社區提交 issue,歡迎在社區繼續討論設計和代碼共建。

怎么樣!現在你至少看的懂這個方舟編譯器架構的大體流程了吧,是不是發現其實并沒有那么難理解!那就對了,萬事開頭難,慢慢的一切都會簡單起來~ 至少去知x上看看這些評論都看懂了啊,如何看待方舟編譯器于 2019 年 8 月 31 日開源? - 知乎,是不是很開心~

詳細可見官方網頁:方舟編譯器 OpenArkCompiler - FAQ

龍書、虎書、鯨書 --- 編譯原理三大圣書

  1. 龍書:《編譯原理》(編譯原理 技術與工具)(Compilers: Principles,Techniques, and Tools)
  2. 虎書:《現代編譯原理 — C語言描 》(Modern Compiler Implement in C)
  3. 鯨書:《高級編譯器設計與實現》(Advanced Compiler Design and Implementation)

龍書:《編譯原理》是編譯領域無可替代的經典著作,被廣大計算機專業人士譽為“龍書”。
虎書:增加了數據流分析、循環優化、內存管理等內容。
鯨書:包含了一些更比較高級的編譯器的設計和實現。

大家是不是瞬間感覺自己就要買這幾本書呢!!!我到底能不能看的懂呢?可以先自測一下自己是不是適配現在就學習編譯原理:

學習編譯原理前自測
  • a. 編譯型語言和解釋型語言的區別是什么?
  • b. 編譯經歷了哪幾個基本過程? 每個過程主要干了什么事情?
  • c. 詳細描述一下你最熟悉的語言中,賦值號的左邊可以由哪些部分組成? 右邊可以由哪些部分組成?
  • d. 什么是遞歸? 如何終止一個遞歸行為?
  • e. 什么是貪心過程?
  • f. 聽說過 KMP 嗎? 介紹一下它的基本思想.
  • g. 生成樹是什么?
  • h. 你覺得編程語言和自然語言最重要的區別有哪些?
  • i. 什么是有限狀態自動機? 你知道幾種不同的自動機類型? 它們之間的區別和聯系?
  • j. 內存被人為的劃分成了哪幾種不同的類型, 它們之間的區別和聯系?
  • k. 什么是中斷? CPU 在響應中斷時會做什么事情?
  • l. 你最熟悉的語言有垃圾回收機制嗎? 若有描述它進行垃圾回收的原理, 若沒有則描述你在編寫程序時是如何管理內存的?

本節內容來自:如何學習編譯原理? - 歐長坤的回答 - 知乎

3、總結

終于到總結部分啦!這個文章,之前給我們組內同學分享時,在回顧都忘記了一大部分,另外在寫成文字時,發現有很多東西需要考證,每篇文章花了很多心思,正好2020年新型肺炎冠狀病毒都在家里,正好有這時間。而 維基百科 就是一個很棒的網站,關于大多數知識和歷史都能查到,真的很有趣!

關于編譯器的知識有太多了,深入的還可以自己寫一個編譯器!這里就達不到這樣的層次,所以就提一下,有需要的同學可以自行搜索。關于LLVM的知識也還有很多沒有講到,比如抽象語法樹(AST),前端 Clang 是重中之器,Clang 插件開發等,還有中間端的 Pass,后端的Mach-O 和 CPU 執行 Mach-O 的過程等。

最后,本文還是有很多細節無法用文字記錄下來,大家可以閱讀下面的參考鏈接,這樣收獲會更大。關于編譯器鏈接器就到這里先,對于大家理解這個概念應該是沒有問題啦!具體的實現細節,需要大家多學習,如果有能力,可以看看龍書!虎書!鯨書! 想想也是一件快樂的事件!

2020年,手機只是小小一部分,智慧家居大屏、穿戴、車機、音響、手表、PC等等各種各樣設備,作為開發者,我們不要只關注自己開發的App,應該去理解這個世界發生什么變化,為什么變化,怎么變化,抓住變化!當然我承認世界是掌握于小數人,但能先抓住自己!這就是好的開始~


注:更多關于 iOS 開發和程序開發相關的內容,可以查看系列,目前還在連載中 【學習總結】iOS開發高手課 -- (連載中) | iHTCboy's blog,以上,希望對你有用!

參考

WWDC

Article


  • 如有侵權,聯系必刪!
  • 如有不正確的地方,歡迎指導!
  • 如有疑問,歡迎在評論區一起討論!


注:本文首發于 iHTCboy's blog,如若轉載,請注來源

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,333評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,491評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,263評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,946評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,708評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,409評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,939評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,774評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,641評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,872評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,650評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內容