要將這麼龐大且跨領域的系統從零建構起來。這不單單只是一個物理模擬器,本質上它是一個編譯器後端與高效能運算(HPC)架構的結合。 在正式讓粒子跑起來、讓數值模擬產生結果之前,要先把軟體寫出來。因此,在正式讓粒子跑起來、讓數值模擬產出炫砲的結果之前,我們得先面對骨感的現實——把底層的軟體架構寫出來。
無論多複雜的系統,先來個 LLVM - hello.ll吧。
最簡單無腦的方法,就是直接去 GitHub 的 llvm-project Releases 頁面,拖一個預先編譯好的 Binary 版本回來用。 因為版本變動的速度實在太快了,今年六月還在 LLVM 22.1.8 ,現在就更新到 LLVM 23.1.0-rc3。不用糾結最新版AI懂不懂, 反正 AI 總是趕不上更新的速度。
; Define the main function --> int main ( )
define i32 @main() {
; Get a pointer to the first element of our string array
%mystr = getelementptr [14 x i8], [14 x i8]* @.str, i64 0, i64 0
; Call the 'puts' function with the string pointer
call i32 @puts(i8* %mystr)
; Return 0 from main
ret i32 0
}
define i32 @main()
define:這告訴 LLVM 在此定義了一個函數(相對於 declare,後者僅用來引用在其他地方定義的外部函數)。
i32:一個 32 位元的有號整數(signed integer)。
@main:函數的名稱。
@:代表這是一個全域識別碼(global identifier)。在 LLVM IR 中,所有函數與全域變數皆以 @ 開頭。
():參數列表(parameter list)。
結果:define i32 @main():定義了一個名為 main 的全域函數,不接受任何參數,並回傳一個 32 位元的有號整數。
getelementptr (GEP) 指令%mystr = getelementptr [14 x i8], [14 x i8]* @.str, i64 0, i64 0
%mystr:一個區域識別碼(由 '%' 表示),用來存放計算後位址的暫存器。
getelementptr:此指令用於取得複合結構型別(如陣列或結構體)中子元素的記憶體位址。
[14 x i8]:指定被逐步走訪的基礎型別([14 x i8],即由 14 個 8 位元整數/字元所組成的陣列)。
[14 x i8]*:此參數提供了全域字串變數(@.str)的型別與位址。
第一個索引值 (i64 0):用於指標本身的位移。因為 @.str 是一個指向該陣列的指標,索引值 0 代表停留在 @.str 所指向的記憶體區塊起始處。
第二個索引值 (i64 0):用於深入陣列結構內部。索引值 0 代表取得該 14 位元組陣列中第一個元素(索引 0)的位址。
結果:%mystr 現在儲存了一個簡單的 i8*(指向字元的指標,相當於 C 語言中的 char*),它直接指向該字串的第一個字母。
const char .str[14] = "Hello, World!\0"; // The global array
const char* mystr = &.str[0];
call i32 @puts(i8* %mystr)
call: 執行一個函數。i32: 表示被呼叫的函數會回傳一個 32 位元的整數。puts 來自標準 C 函式庫(libc)。(i8* %mystr): 傳遞給該函數的參數。ret i32 0
ret: 回傳(return)指令。i32 0: 回傳值。表示程式執行成功,沒有發生錯誤。如果用 C 語言來寫,對應的程式碼會長得像這樣:
const char .str[14] = "Hello, World!\0"; // The global array
int main() {
// This is what the GEP instruction does:
const char* mystr = &.str[0];
puts(mystr);
return 0;
}
# Compile using the clang binary in the neighboring folder
../llvm-binary/bin/clang hello.ll -o hello
# Run the finished executable
./hello
../llvm-binary: 就是從 github llvm-project Releases 頁面拖回來個預先編譯好的 Binary 。沒錯,不是組合語言,但是很像組合語言,算比較像人話的組合語言吧。
[1] Getting Started with the LLVM System
[2] mrjameshamilton/llvm-helloworld
同步備份於 https://github.com/botszhuang/digital_garden/blob/main/ithome_30_2026/day2.md