# 計算機組織概論
在深入探討技術細節之前,讓我們先釐清「計算機組織 (Computer Organization)」和「計算機架構 (Computer Architecture)」這兩個經常一起出現但意義不同的詞。
計算機架構 (Computer Architecture):這是「What」的層面 。它像是電腦的設計藍圖,從程式設計師的角度定義電腦的功能。它描述了電腦能做什麼,包括它能理解的指令集 (ISA)、可用的暫存器、記憶體定址方式等 。架構是抽象的、概念性的 。
計算機組織 (Computer Organization):這是「How」的層面 。它描述了如何實現這個設計藍圖。它關注的是硬體元件的物理結構、它們如何被連接在一起,以及它們之間的互動方式,以達成架構所定義的功能 。組織是具體的、物理的。
## 1. 馮紐曼架構:現代電腦的設計藍圖
這是幾乎所有現代電腦的基礎設計。
核心概念:儲存程式電腦 (Stored-Program Computer)
革命性的想法:程式的指令 (Instructions) 和要處理的資料 (Data) 都存放在同一個記憶體中。
這讓電腦成為可以執行任何程式的「通用」機器,而不是只能做單一任務的「專用」機器。
### 五大核心單元
- 記憶體 (Memory):儲藏室,存放指令和資料。
- 中央處理器 (CPU):電腦的大腦,負責執行指令。
- 控制器 (CU):指揮中心,解讀指令並協調各單元。
- 算術邏輯單元 (ALU):計算中心,執行數學和邏輯運算。
- 輸入設備 (Input):讓我們能對電腦下指令(如:鍵盤、滑鼠)。
- 輸出設備 (Output):讓電腦能呈現結果給我們(如:螢幕、印表機)。

### 馮紐曼瓶頸 (Von Neumann Bottleneck)
由於 CPU 和記憶體之間只有一條共用通道,而 CPU 速度遠快於記憶體,導致 CPU 常常需要花時間等待資料,成為效能瓶頸 。
## 2. CPU 的工作台:暫存器 (Register) vs. 記憶體 (RAM)
CPU 處理資料時,會在不同層級的儲存裝置間移動資料。其中最核心的就是暫存器和主記憶體 (RAM)。
| 屬性 | CPU 暫存器 (Registers) | 主記憶體 (RAM) |
| ---- | ---------------------- | -------- |
| 角色 | CPU 的即時工作台 | 程式的主要舞台、儲藏室 |
| 速度 |極快,內建於 CPU 中 |較慢,在主機板上|
| 容量 |極小 (約 64 位元) |極大 (GB 等級)|
| 用途 | 存放 CPU 當下正在運算的資料 |存放所有執行中的程式與其資料|
|存取方式 |CPU 指令直接操作 (如 ADD R1, R2) |需透過位址來存取 (如 LOAD, STORE)|

簡單比喻:RAM 就像廚房的大儲藏室,而暫存器是廚師面前的切菜板。廚師 (CPU) 會先把食材 (資料) 從儲藏室拿到切菜板上,處理完再放回去。
### 特殊暫存器
除了通用暫存器 (General Registers, 如 EAX、EBX),CPU 還有一些特殊用途的暫存器:
| 暫存器名稱 | 功能 |
| -------- | ---- |
| **PC (Program Counter / 指令計數器)** | 保存下一條要執行的指令位址,控制程式流程。
| **IR (Instruction Register / 指令暫存器)** | 保存目前正在解碼或執行的指令。 |
| **Flags Register (狀態暫存器, EFLAGS/FLAGS)** | 保存運算結果的狀態 (如零旗標 ZF、進位旗標CF、溢位旗標 OF)。 |
| **SP (Stack Pointer / 堆疊指標)** | 指向目前堆疊的頂端,用於函式呼叫、區域變數與 PUSH/POP 操作。 |
| **BP (Base Pointer / 基底指標, Frame Pointer)** | 指向函式堆疊框架的基底,協助存取區域變數與參數。 |
#### 實際例子
1. Program Counter(PC)
```
jmp target ; PC 會被更新為 target 的位址
```
2. Instruction Register (IR)
```
mov eax, 5 ; 指令被抓取後會放入 IR,CPU 解碼並執行
```
3. Stack Pointer (SP)
```
push eax ; SP 減少,並把 EAX 的值壓入堆疊
pop ebx ; SP 增加,並把堆疊頂端的值取出到 EBX
```

4. Base Pointer (BP)
> Frame(堆疊框架) 是每次呼叫函式時,在 stack 上劃出的專屬區塊。

## 3. 權限分界:使用者模式 vs. 核心模式
為了系統的穩定與安全,CPU 有兩種運作模式,由硬體直接強制執行 。
### 使用者模式 (User Mode / Host Code)
執行者:一般應用程式 (如 Chrome, Word, 遊戲) 。
權限:受限制。不能直接存取硬體或作業系統核心資料 。
保護:每個程式在獨立的記憶體空間執行。一個程式崩潰,不會影響到其他程式或整個系統 。
### 核心模式 (Kernel Mode / System Code)
執行者:作業系統核心、硬體驅動程式 。
權限:最高權限。可存取所有硬體和記憶體,執行任何指令 。
風險:在核心模式下發生錯誤,會導致整個系統當機(例如 Windows 的藍白畫面)。
### 如何切換?系統呼叫 (System Call)
當使用者模式的程式需要存取硬體時(如讀取檔案),它會發出「系統呼叫」請求,暫時切換到核心模式,讓作業系統代為處理,完成後再切換回來 。

## 4. RISC-V:開放的硬體語言
指令集架構 (ISA) 是什麼?
是軟體與硬體之間的溝通「語言」或契約,定義了 CPU 能看懂的所有指令 。
兩種設計哲學
- CISC (複雜指令集):指令功能強大但複雜,如個人電腦的 x86 架構 。
- RISC (精簡指令集):指令數量少、功能單純但高效,如手機的 ARM 架構和 RISC-V 。
### RISC-V 的革命性之處
完全開放且免費:任何人都可以用它來設計晶片,不需支付授權費,打破了傳統由少數公司壟斷的局面 。
模組化設計:像樂高積木,可依需求選擇性地加入功能擴充,讓晶片設計更具彈性與客製化 。 這在ARM和x86上較難做到 。
未來趨勢:因其開放、彈性、安全的特性,正被 Google、NVIDIA 等大廠用於 AI、物聯網等各種領域 。
## 5. 常見組合語言指令範例
組合語言是一種接近硬體、屬於低階的程式語言它用簡單的文字助記符(如 MOV、ADD、SUB)直接對應CPU或微控制器的指令集。以下是幾種最基本的指令類型:
- 資料傳輸指令 (Data Transfer Instructions)
MOV (Move):將資料從來源 (source) 複製到目的地 (destination)。這是最常見的指令 。
```
MOV RAX, RBX ; 將 RBX 暫存器的值複製到 RAX 暫存器
MOV count, 10 ; 將常數 10 存入名為 count 的記憶體變數
MOV AL, [my_var] ; 將 my_var 記憶體位址處的 1 個位元組載入到 AL 暫存器
```
- PUSH / POP:在堆疊 (Stack) 上存入或取出資料。堆疊是一個後進先出 (LIFO) 的記憶體區域,常用於函式呼叫時保存暫存器狀態或傳遞參數 。
- PUSH:將運算元的值壓入堆疊頂部,並將堆疊指標 (RSP) 向下移 。
- POP:從堆疊頂部取出值到運算元,並將堆疊指標向上移 。
```
PUSH RAX ; 保存 RAX 的值到堆疊
POP RAX ; 從堆疊恢復 RAX 原本的值
```
> 注意:PUSH 和 POP 的次數必須成對,否則會導致堆疊不平衡,程式可能會崩潰 。
- 算術運算指令 (Arithmetic Instructions)
ADD / SUB:執行加法或減法 。
```
MOV EAX, 100
ADD EAX, 50 ; EAX = 100 + 50 = 150
SUB EAX, 25 ; EAX = 150 - 25 = 125
```
- INC / DEC:將運算元的值加一或減一,比 ADD/SUB 更有效率 。
```
MOV ECX, 10 ; ECX 作為迴圈計數器
loop_label:
... ; ... 迴圈內的程式碼...
DEC ECX ; 計數器減一
JNZ loop_label ; 如果 ECX 不為零,則跳回 loop_label
```
- 邏輯與比較指令 (Logical and Comparison Instructions)
AND / OR / XOR:執行位元運算的 AND、OR、XOR 。
XOR 一個暫存器與其自身是將其清零的常用技巧。(不同時為1,相同時為0)
```
XOR EAX, EAX ; 比 MOV EAX, 0 更有效率
```
| 屬性 | XOR EAX, EAX | MOV EAX, 0 |
| -------- | ------------------ | ------------------------------- |
| 指令長度 | 2個位元組 | 5個位元組(需要額外的立即數編碼) |
| 立即數的處理 | 否 | 是 |
| 資料依賴 | 無依賴,容易平行化 | 可能造成部分暫存器依賴 |
| CPU優化 | 是 | 否 |
- CMP (Compare):比較兩個運算元。它實際上是執行減法,但不儲存結果,而是根據結果設定 CPU 的狀態旗標 (Flags),如零旗標 (ZF)、正負號旗標 (SF)。
- CMP A, B 執行 A - B:
- 如果 A == B,結果為 0,ZF 設為 1。
- 如果 A!= B,結果不為 0,ZF 設為 0。
- 如果 A < B (無號數),會產生借位,CF 設為 1。
CMP 幾乎總是與條件跳躍指令(如 JE, JNE, JG, JL)一起使用,以實現 if-else 或迴圈邏輯。
```
MOV EAX, 10
CMP EAX, 10 ; 比較 EAX 與 10。 EAX - 10 = 0,所以 ZF=1
JE is_equal ; Jump if Equal (因為 ZF=1),跳到 is_equal 標籤
CMP EAX, 20 ; 比較 EAX 與 20。EAX - 20!= 0,所以 ZF=0
JNE is_not_equal ; Jump if Not Equal (因為 ZF=0),跳到 is_not_equal 標籤
```
- TEST:把兩個操作數做AND運算,但不會保存結果,只會更新旗標,如零旗標 (ZF)、正負號旗標 (SF)、奇偶旗標(PF)、進位旗標(CF)、溢位旗標(OF)。
```
TEST EAX, EAX ; 比 CMP EAX, 0更有效率
JZ is_zero ; 如果 EAX == 0,跳轉
JNZ not_zero ; 如果 EAX != 0,跳轉
```
| 屬性 | TEST EAX, EAX | CMP EAX, 0 |
| -------- | ------------------ | ------------------------------- |
| 指令長度 | 2個位元組 | 3個位元組(需要額外的立即數編碼) |
| 立即數的處理 | 否 | 是 |
| CPU優化 | 是 | 否 |
TEST 也常被用來做位元遮罩,檢查某些位元是否為1,用於檔案權限判斷、狀態旗標判斷。
```
test eax, 0x04 ; 檢查 bit2 是否為 1
jnz bit2_is_set
```
- Bit Test系列,適合需要「狀態切換」又「要知道舊狀態」的情況:
- BT(Bit Test):檢查某一 bit → 放到 CF。
- BTS(Bit Test and Set):檢查並設為 1。
- BTR(Bit Test and Reset):檢查並清為 0。
- BTC(Bit Test and Complement):檢查並翻轉。
```
bt eax, 5 ; 檢查 EAX 的 bit5,結果放到 CF
jc bit5_is_set ; 如果 CF=1 → bit5=1
bts eax, 3 ; 設定 bit3
btr eax, 7 ; 清除 bit7
btc eax, 0 ; 翻轉 bit0,原本在 CF
jc was_on ; 如果 CF=1,代表原本是開的
jnc was_off ; 如果 CF=0,代表原本是關的
```