Thanks to visit codestin.com
Credit goes to github.com

Skip to content

paulboul1013/Brainfuck_Interpreter

Repository files navigation

Brainfuck 解譯器與編譯器

一個功能完整的 Brainfuck 工具集,包含解譯器和 x86 編譯器,能夠執行或編譯標準的 Brainfuck 程式。

功能特色

  • Brainfuck 解譯器 - 直接執行 Brainfuck 程式
  • x86-32 編譯器 - 將 Brainfuck 編譯為原生 32 位元機器碼
  • x86-64 編譯器 - 將 Brainfuck 編譯為原生 64 位元機器碼
  • LLVM 後端 - 產生 LLVM IR,跨平台以 clang 執行
  • 高效能 - 編譯版本比解譯版本快 4-10 倍
  • 系統調用 - 編譯器使用 Linux 系統調用,不依賴 C 標準庫
  • 30,000 記憶體單元 - 符合 Brainfuck 標準規範

簡介

Brainfuck 是一種極簡主義的程式語言,只包含 8 個指令:

  • > - 指標向右移動
  • < - 指標向左移動
  • + - 當前記憶體單元值加 1
  • - - 當前記憶體單元值減 1
  • . - 輸出當前記憶體單元的值(ASCII 字元)
  • , - 從輸入讀取一個字元到當前記憶體單元
  • [ - 如果當前記憶體單元值為 0,跳轉到對應的 ] 之後
  • ] - 如果當前記憶體單元值不為 0,跳轉回對應的 [ 之後

本解譯器提供 30,000 個記憶體單元(8 位元無符號整數),支援完整的 Brainfuck 語法。

編譯與執行

debug模式

# 一般模式
./bf hello.bf

# 除錯模式(預設視窗 8)
./bf -d hello.bf

# 除錯模式 + 自訂視窗寬度
./bf -d -w 12 hello.bf
#
./bf --debug --debug-window 12 hello.bf

方式 1:使用解譯器(簡單快速)

編譯解譯器

gcc main.c -o bf

執行

./bf hello.bf

輸出:

Hello World!

優點:簡單、快速啟動 缺點:執行速度較慢


方式 2:使用編譯器

1. 編譯 Brainfuck 編譯器

gcc -o compiler_x86 compiler_x86.c

2. 將 Brainfuck 程式編譯為組語

./compiler_x86 hello.bf > hello.s

3. 組譯為可執行文件

gcc -m32 -nostdlib -no-pie -o hello-x86 hello.s

4. 執行編譯後的程式

./hello-x86

輸出:

Hello World!

優點:執行速度快 4-10 倍 缺點:需要額外的編譯步驟


方式 3:使用 x86-64 編譯器(64 位元)

1. 編譯 Brainfuck 64 位元編譯器

gcc -o compiler_x86_64 compiler_x86_64.c

2. 將 Brainfuck 程式編譯為 64 位元組語

./compiler_x86_64 hello.bf > hello_x64.s

3. 組譯為 64 位元可執行文件

gcc -nostdlib -no-pie -o hello_x64 hello_x64.s

4. 執行編譯後的程式

./hello_x64

輸出:

Hello World!

優點

  • 原生 64 位元架構支援
  • 使用現代 syscall 指令
  • 不需要 multilib 支援
  • 更好的系統相容性

缺點:需要額外的編譯步驟


方式 4:使用 LLVM 後端(跨平台)

先決條件

請先安裝 LLVM/Clang 工具鏈(含 clangllclli):

# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y clang llvm llvm-runtime

1. 編譯 LLVM IR 產生器

在專案根目錄:

gcc -O2 -o main llvm/llvm.c
# 或(在子資料夾內編譯)
# make

2. 產生 LLVM IR

./main hello.bf > hello.ll

3. 使用 clang 直接產生可執行檔

clang -O2 hello.ll -o hello
./hello

(可選)使用 llc + clang:

llc -O2 -filetype=obj hello.ll -o hello.o
clang hello.o -o hello
./hello

(可選)使用 LLVM 直譯器 lli 執行:

lli hello.ll

注意事項

  • 產生的 IR 內含 @llvm.memset.p0i8.i64 宣告,直接以 clang/llc 處理即可,無需額外連結。
  • 產生器會自動合併連續的 + - > < 指令,並正確處理巢狀 [] 迴圈。
  • 若 Brainfuck 程式括號不匹配,產生器會直接報錯。

方式 5:即時直譯器(互動模式)

在互動模式下,你可以逐鍵輸入 ><+-.,[],每個指令會立即執行,並即時渲染記憶體視窗與輸出。

編譯

cd immediate_interpreter
make

執行

./bf_immediate

操作說明

  • 輸入 Brainfuck 指令:><+-.,[]
  • Space 鍵:清除所有輸出顯示與狀態(重置)
  • 逗號 ,:會讀取下一個按鍵作為輸入資料
  • ESCCtrl-C 離開
  • 畫面會顯示:
    • 程式片段與目前 IP
    • 輸出緩衝(最後 20 字元)
    • 記憶體視窗(固定寬度 50,每 10 個單位交叉顯示),並以 ^ 指示目前指標

編譯器實作原理

x86-32 編譯器 (compiler_x86.c)

compiler_x86.c 將 Brainfuck 程式轉換為 x86-32 組合語言:

Brainfuck x86-32 組語 說明
> incl %ecx 指標遞增
< decl %ecx 指標遞減
+ incb (%ecx) 記憶體值遞增
- decb (%ecx) 記憶體值遞減
. int $0x80 (sys_write) 輸出字元
, int $0x80 (sys_read) 輸入字元
[ cmpb $0, (%ecx) + je 條件跳轉(為 0 跳出)
] cmpb $0, (%ecx) + jne 條件跳轉(非 0 跳回)

關鍵特性

  • 使用 Linux 系統調用(int 0x80),無需 C 標準庫
  • 入口點為 _start,完全獨立運行
  • 靜態分配 30,000 字節記憶體
  • 使用 %ecx 暫存器作為資料指標
  • 暫存器分配優化
    • %esi = 常數 1(用於 sys_write, stdout, 長度)
    • %edi = 常數 0(用於 stdin)
    • 減少系統調用時的立即值載入次數

x86-64 編譯器 (compiler_x86_64.c)

compiler_x86_64.c 將 Brainfuck 程式轉換為 x86-64 組合語言:

Brainfuck x86-64 組語 說明
> incq %r12 指標遞增(64位元)
< decq %r12 指標遞減(64位元)
+ incb (%r12) 記憶體值遞增
- decb (%r12) 記憶體值遞減
. syscall (sys_write) 輸出字元(64位元系統調用)
, syscall (sys_read) 輸入字元(64位元系統調用)
[ cmpb $0, (%r12) + je 條件跳轉(為 0 跳出)
] cmpb $0, (%r12) + jne 條件跳轉(非 0 跳回)

關鍵特性

  • 使用 64 位元 Linux 系統調用(syscall),無需 C 標準庫
  • 入口點為 _start,完全獨立運行
  • 靜態分配 30,000 字節記憶體
  • 使用 %r12 暫存器作為資料指標
  • RIP-relative 尋址方式(位置獨立代碼)
  • 系統調用參數使用 %rax, %rdi, %rsi, %rdx
  • 暫存器分配優化
    • %r13 = 常數 1(用於 sys_write, stdout, 長度)
    • %r14 = 常數 0(用於 sys_read, stdin)
    • 減少系統調用時的立即值載入次數,提升性能

已完成功能

  • Brainfuck 解譯器 - 完整實作,支援所有 8 種指令
  • x86-32 編譯器 - 使用系統調用,不依賴外部庫
  • x86-64 編譯器 - 64 位元原生支援,使用現代 syscall 指令
  • LLVM 後端 - 產生 LLVM IR,支援多平台與 LLVM 工具鏈
  • 效能優化 - 編譯版本比解譯版本快 4-10 倍
  • 指令合併優化 - 自動將連續的 +++ / --- / >>> / <<< 合併為單一指令,減少指令數量
  • 迴圈展開優化 - 自動展開簡單迴圈(如 [-][+][>][<] 等),優化效能
  • 死代碼消除優化 - 自動移除相互抵消的指令(如 +--+><<> 等),提升編譯效率
  • 暫存器分配優化 - 預先分配暫存器存儲常用常數,減少重複的立即值載入,提升執行效率
  • 範例程式 - 提供 Hello World、Mandelbrot、Hanoi 等範例

未來實作

平台編譯器

  • LLVM 後端 - 使用 LLVM IR,支援多平台

編譯器優化

  • 指令合併 - 將連續的 +++ 優化為 addb $3,和其他->,<等相關符號
  • 迴圈展開 - 優化簡單迴圈結構([-][+][>][<] 等)
  • 死代碼消除 - 移除相互抵消的無效指令(如 +--+><<> 等)
  • 暫存器分配 - 更有效利用 CPU 暫存器

其他功能

  • 除錯模式 - 顯示執行過程與記憶體狀態
  • 即時編譯 - 可即時輸入 brainfuck 符號,並即時顯示記憶體狀態

About

BrainFuck interpreter and compiler

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages