Skip to content

Commit

Permalink
真言生成.變數儲存
Browse files Browse the repository at this point in the history
  • Loading branch information
MROS committed Oct 2, 2024
1 parent 8858b6c commit 62c0f1f
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 1 deletion.
67 changes: 67 additions & 0 deletions book/零.一版/精五真言生成.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
至此,貧道已經展示了零.一版音界咒的分詞、剖析、語義檢查,若程式能通過這些步驟,代表它完全合法。接下來,就可以生成目標碼了,在本指引中,貧道會示範如何生成精五真言(RISC-V)。

## 變數儲存
熟悉 C 語言的道友想必都曉得,全域變數與區域變數在程序執行時是放在不同位置。全域變數會放在數據段(data section),在整個程序執行的過程都佔用一塊記憶體空間;而區域變數則是則是存放在函式調用時臨時開的棧禎。

零.一版音界咒的變數可以視做全域的,畢竟該版本尚無函式調用的概念。

### 精五真言的數據段

很容易就能用精五真言設定全域變數,一下是範例`數據段.S`

```assembly
.section .data
甲:
.word 50 # .word 表示開闢 32 位元的空間,該空間的值為 50
.section .text
.global _start
_start:
lw t0, 甲 # t0 = *(u32*)甲
li a7, 93 # RISCV Linux 中 exit 系統呼叫編號是 93
mv a0, t0 # a0 = t0
ecall # 執行系統呼叫 exit(t0)
```

同樣交叉編譯並以 qemu 模擬
```
riscv64-unknown-elf-gcc -nostdlib 數據段.S # 編譯後應得 a.out 檔案
qemu-riscv64 a.out # qemu-riscv64 並非單單模擬裸機,還實作了部分系統呼叫
echo $? # 可以看到上一個程序的結束碼是 50
```

`數據段.S` 首先在數據段 `.section .data` ,中用 `.word` 開闢 32 位元的空間,前方的``是一個標籤,在後續程式段的真言中會被代換為該空間的位址。

再來看 `_start` 的第一行 `lw t0, 甲`,lw 是 load word 的縮寫,效果是從位址甲開始讀取 32 位元放進 t0 暫存器。 `lw` 執行完後, `t0` 就是 `50` 了,最後 `mv a0, t0` 把程序結束碼設為 50。

`lw` 相對應,`sw`(store word)能夠將暫存器的值寫入某個記憶體位址,但 `sw` 要多加一個參數,`sw t0, 甲, rt``rt` 可以是任意通用暫存器。


### 選讀:為什麼 sw 要三個參數
接三個參數的 `sw rd, 標籤, rt` 是偽指令,組譯後會變為兩條指令:

```
auipc rt, 標籤[31:12]
sw rd, 標籤[31:12](rt)
```

其大概意思是用先把 rt 的值弄成成標籤的位址,再把 rt 所在位址的 32 位元存進 rd 。

那為何 `lw rd, 標籤` 就不需要額外暫存器來幫忙存位址呢?它也是會編譯成兩條真言的偽指令吧! 因為`rd`在載入時能重複用。
```
auipc rd, 標籤[31:12] # 反正等等 rd 的值等等也要被改了,順便當位址用
lw rd, 標籤[31:12](rd) # rd 既是記憶體位址,又是要被寫入的暫存器
```

`sw` 的 rd 要是重複用,還沒把它的值寫到記憶體,自己就先被汙染了:

```
auipc rd, 標籤[31:12] # rd 的值已被汙染
sw rd, 標籤[31:12](rd) # 把被汙染的值寫到記憶體
```

所以 `sw rd, 標籤, rt` 的第三個參數 rt 省不了。

## 運算
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

## 實驗環境架設

絕大部分的人手邊都沒有精五架構的板子,需要先安裝
絕大部分的人手邊都沒有精五架構的板子,在其他架構的機器上,需要先安裝一些工具才能模擬精五架構:

- 交叉編譯器工具鏈
- 精五模擬器(本作選擇使用 qemu)
Expand Down

0 comments on commit 62c0f1f

Please sign in to comment.