---
title: 「你所不知道的 C 語言:編譯器原理和案例分析」 筆記
tags: Computer Science,System Software
description: 2019.08.10
---
「你所不知道的 C 語言:編譯器原理和案例分析」 筆記
===
###### 2019.08.10 *Copyright © 2019 by srhuang*
![](https://i.imgur.com/cQJG33Y.png)
[影片](https://youtu.be/Cf9kXtLuQZ8)
[講義](http://hackfoldr.org/dykc/https%253A%252F%252Fhackmd.io%252Fs%252FH1ZzeiCIQ)
Original by [jserv](http://wiki.csie.ncku.edu.tw/User/jserv)
---
## 如何打造一個具體而微的 C 語言編譯器?
* 700 行系列:https://youtu.be/Cf9kXtLuQZ8?t=65
* AMaCC:https://youtu.be/Cf9kXtLuQZ8?t=363
* 是由台灣國立成功大學師生開發的 self-compiling 的 C 語言編譯器。
* 支援 just-in-time (JIT) 編譯和執行。
* 原始程式碼還不到 1500 行。
* IR (Intermediate representation), dynamic linking, relocation, symbol table, parsing tree, language frontend, Arm 指令編碼和 ABI。
* AMaCC 產生出來的執行檔:https://youtu.be/Cf9kXtLuQZ8?t=623
## 編譯器和軟體工業強度息息相關
* IBM 簡報:https://youtu.be/Cf9kXtLuQZ8?t=666
* 軟體驗證環境相當重要。
* 形式化驗證:https://youtu.be/Cf9kXtLuQZ8?t=848
## 用1500 行建構可自我編譯的 C 編譯器:
* 自我編譯才能讓整個系統自我演化:https://youtu.be/Cf9kXtLuQZ8?t=1090
* Self-host:https://youtu.be/Cf9kXtLuQZ8?t=1356
* 如果無法 self-host (自我編譯),就需要 bootstrapping,有三種方法:
* 徒手把 machine code 寫出來。
* 用另一個語言寫出來的 compiler 來 compile。
* 透過 interpreter 建立 translator。
* Clang (LLVM) 花了三年才能夠達到 self-host。
* 當編譯器能夠 self-host,才能說是 fully-functional。
* 支援 JIT (just-in-time) compiler:https://youtu.be/Cf9kXtLuQZ8?t=1834
* 輸出 ELF 檔案格式。
* How AMacc works?:https://youtu.be/Cf9kXtLuQZ8?t=2000
* parse code 轉成 IR。
* 直接透過 codegen 轉成 machine code。
* relocation。
* IR (Intermediate Representation):https://youtu.be/Cf9kXtLuQZ8?t=2187
* 沒有 IR,會無法有效率的重用最佳化技術。
* 「電腦科學所有的問題,都可以引入中間層去解決。」
* 把 token 轉成 IR 的 opcode。
* 在 codegen 裡把 opcode 轉成 machine code。
* opcode 會透過載入系統函式庫 libc,來使用系統呼叫。
* ELF format:https://youtu.be/Cf9kXtLuQZ8?t=3075
* Executable and Linkable Format。
* ELF Header:Program header, Section header。
* Section and Segment。
* Interpreter 代表與 dynamic linker 有關。
## 背景知識
* 編譯器和最佳化原理篇:https://youtu.be/Cf9kXtLuQZ8?t=3616
* Skymizer (台灣發展軟體公司) 的 onnc。
* 編譯器最佳化的範例。
* SSA (Static Single Assignment):SSA 把原本複雜的條件和程式邏輯轉化為 Graph
* 編譯器的最佳化背後都是數學。
* Compilation Flow。
* Procedures:argument 傳遞的形式 / parameter 接收的數值。
* 動態連結器和執行時期篇:https://youtu.be/Cf9kXtLuQZ8?t=4560
* 實作跨越程式語言的交流。
* LD_PRELOAD 環境變數,可以替換掉 malloc。
* Compilation Unit:建議 local function 要宣告成 static。
* Modern C:必讀的教材。
* 動態連結支援:GOT and PLT。
* Relocation。
* Browser Linker。
* [虛擬機器設計與實作](https://hackmd.io/@jserv/SkBsZoReb?type=view):https://youtu.be/Cf9kXtLuQZ8?t=5807
* 主要分成 process virtual machine and system virtual machine。
* RTMux:無人機。
## C 程式的解析和語意
* descent 點評幾本編譯器設計書籍:https://youtu.be/Cf9kXtLuQZ8?t=6345
* OGC (Ordinary Garbage Collector):https://youtu.be/Cf9kXtLuQZ8?t=6550
* 手把手教你建構 C 語言編譯器:https://youtu.be/Cf9kXtLuQZ8?t=6853
* c4:用四個 function 實作出 C語言的直譯器。
* 編譯器雜談。編譯器是電腦科學的第一個正式有系統的學科。
* 設計:https://youtu.be/Cf9kXtLuQZ8?t=7217
* token。
* Compilers and Virtual Machine。
* 虛擬機:https://youtu.be/Cf9kXtLuQZ8?t=7482
* 建構 opcode。
* 中間的 IR 不要離 machine code 太遠。
* 指令集以 [stack-based](https://en.wikipedia.org/wiki/Stack_machine) 為主。[相對於 register-based]
* 詞法分析器:https://youtu.be/Cf9kXtLuQZ8?t=7932
* compiler lex yacc
* GCC 為了效能考量,捨棄 lex/yacc 直接用手刻,會大幅提升效率。
* 不支援 struct,但是 AMaCC 有支援。
* 遞歸下降:https://youtu.be/Cf9kXtLuQZ8?t=8303
* 語法分析器從上而下分析,稱為遞歸下降。
* 設計編譯器,其實也在探索語法表達式的限制。
* 變量定義:https://youtu.be/Cf9kXtLuQZ8?t=8621
* 表達式:https://youtu.be/Cf9kXtLuQZ8?t=8654
* postfix, infix:要把中序轉成前序或是後序才能使用 stack-based machine。
* 自增自減:p++, p--。
* 逐步開發編譯器:https://youtu.be/Cf9kXtLuQZ8?t=8973
## IR (Intermediate representation)
* interpreter:https://youtu.be/Cf9kXtLuQZ8?t=9062
* AMaCC interpreter branch。
* 可以執行 Bytecode,解讀 opcode。
* JIT,Interpreter, Compiler, JIT from scratch:https://youtu.be/Cf9kXtLuQZ8?t=9179
* Brainf*ck language Interpreter。
* JIT compiler:https://youtu.be/Cf9kXtLuQZ8?t=9321
* 在執行階段動態輸出 machine code,並且執行。
* 利用 mmap 讓原本是 data 的 machine code 可以執行。
* AMaCC IR:https://youtu.be/Cf9kXtLuQZ8?t=9621
* AMaCC JIT 執行:https://youtu.be/Cf9kXtLuQZ8?t=9665
* test/jit.c
* 使用 bsearch 跳過去執行,因為 AMaCC 沒有支援 function type。
* How to JIT - an introduction:https://youtu.be/Cf9kXtLuQZ8?t=9954
* __clear_cache:AMaCC 的 CLCA。
* How to write a very simple JIT compiler:https://youtu.be/Cf9kXtLuQZ8?t=10338
* 跳躍是影響效能很重要的議題,太多的跳躍會影響 cache。
## 總結:https://youtu.be/Cf9kXtLuQZ8?t=10550