# ISA 電腦架構包含兩個主要元素:Instruction Set Architecture(ISA)和 Machine Organization。 ## MIPS ISA 指令類別: * Load/Store: * 這類指令用於將數據 Load 到 register 中或將 register 中的數據Store到 memory 中。例如:lw(載入字)、sw(儲存字)。 * Computational: * 這類指令執行算術和邏輯運算。包括加法、減法、乘法等。例如:add(加法)、sub(減法)。 * Jump and Branch: * 用於控制流程的指令,包括無條件跳躍和有條件分支。例如:j(跳躍)、beq(分支等於)。 * loating Point: * 這類指令用於執行浮點數運算。例如:add.s(浮點數加法)。 * Memory Management: * 這些指令涉及 memory 的管理和保護。例如:tlbwi(將TLB入口寫入)。 * Special: * 這類指令可能包含特殊功能,例如 OS 調用或其他系統級任務。例如:syscall(系統調用)。 ### MIPS 算數 ``` add $s0, $s1, $s2 # f = g + h ``` 將 register $s1 和 $s2 中的值相加,並將計算結果存儲在 $s0 中。 * 這樣的每條指令是32 bits: * 每條MIPS指令都是32 bits 的固定長度。 * 語法的嚴格性: * MIPS指令的語法是嚴格的,每條指令包含一個 operator 和三個 operands。 * 為什麼保持嚴格規律性? * 說明保持嚴格規律性的原因,即簡單性有助於實現和執行,提高性能,同時降低成本。 ## MIPS register * assembly language 不使用 variables,而是使用 register 作為 operands * 操作是在這些 register 上進行的 ![image](https://hackmd.io/_uploads/SyLwqe6K6.png) * 32 個 register,每個 register 寬度為 32 bits * 在MIPS體系結構中,32 bits 被稱為一個字 * 這32個通用 register 分別編號從0到31,可以通過編號來引用。 * 例如,$0 表示 register 0,$1 表示 register 1,以此類推,$31 表示 register 31。 * 除了可以使用編號引用外,MIPS還提供了通過名稱引用 register 的方式。 * 例如,$s0 到 $s7 通常用於表示C語言中的 variables * 而 $t0 到 $t7 則是 temporary register,用於臨時存儲計算中的數據。 * HI和LO register 用於存儲乘法和除法的結果。 * PC(程序計數器)則用於存儲當前指令的地址,指示處理器應該執行的下一條指令。 ## temporary register example 如何編譯以下的 C 語句: `f = (g + h) - (i + j);` 使用temporary register $t0 和 $t1 作為中間變數。 ``` add $t0, $s1, $s2 # t0 = g + h add $t1, $s3, $s4 # t1 = i + j sub $s0, $t0, $t1 # f = (g + h) - (i + j) ``` * add $t0, $s1, $s2: * 把 $s1 和 $s2 中的值相加,結果存儲在 $t0 中。 * add $t1, $s3, $s4: * 把 $s3 和 $s4 中的值相加,結果存儲在 $t1 中。 * sub $s0, $t0, $t1: * 把 $t0 中的值減去 $t1 中的值,結果存儲在 $s0 中。 * 最後這一步計算了 (g + h) - (i + j),最終的結果被存儲在 $s0 中,即變數 f 的值。 ## Memory to Register * MIPS 算術指令是在 register 上執行的,而不是直接在 memory 上。 * 為了在 register 和 memory 之間進行數據轉移,使用 lw(載入字)和 sw(儲存字)等數據傳輸指令。 * 在進行數據轉移時需要指定兩個重要的事物: * register (0 - 31 號) * memory address。 * 將 memory 視為一維數組( array ),使用指向 memory address 的 pointer 和相對於該 pointer 的 Offset(以 bits 為單位)。 #### 舉例來說: `lw $t0, 12($s0)` * operation name:lw 表示載入字(loar word)。 * 接收值的 register :$t0 是接收載入值的register。 * offset(以 bits 為單位):12 是相對於 $s0 的偏移量。 * 包含指向 memory 的 pointer 的 register :$s0 包含指向 memory 的 pointer 。 `lw $t0, 12($s0) `的例子表示: 使用 $s0 中的指針,向後移動 12 個 bits ,然後從計算出的memory address 載入值到register $t0 中。 `g = h + A[8];` * $s1:g * $s2:h * $s3:base address of A 以下是上述c語言換成組合語言的步驟 1. 計算訪問A[8]的offset * A[8]的offset是 4 x 8 = 32 bits 2. 將A[8]加載到 register $t0中 * `lw $t0,32($s3) # $t0 gets A[8]` 3. 將 $t0 register 中的值加到 $s2 register 中的值(h)上,並將結果存儲在 $s1 register(g)中。: * `add $s1, $s2, $t0 # $s1 = h+A[8]`