# 計算機組織概論 在深入探討技術細節之前,讓我們先釐清「計算機組織 (Computer Organization)」和「計算機架構 (Computer Architecture)」這兩個經常一起出現但意義不同的詞。 計算機架構 (Computer Architecture):這是「What」的層面 。它像是電腦的設計藍圖,從程式設計師的角度定義電腦的功能。它描述了電腦能做什麼,包括它能理解的指令集 (ISA)、可用的暫存器、記憶體定址方式等 。架構是抽象的、概念性的 。   計算機組織 (Computer Organization):這是「How」的層面 。它描述了如何實現這個設計藍圖。它關注的是硬體元件的物理結構、它們如何被連接在一起,以及它們之間的互動方式,以達成架構所定義的功能 。組織是具體的、物理的。 ## 1. 馮紐曼架構:現代電腦的設計藍圖 這是幾乎所有現代電腦的基礎設計。   核心概念:儲存程式電腦 (Stored-Program Computer) 革命性的想法:程式的指令 (Instructions) 和要處理的資料 (Data) 都存放在同一個記憶體中。   這讓電腦成為可以執行任何程式的「通用」機器,而不是只能做單一任務的「專用」機器。 ### 五大核心單元  - 記憶體 (Memory):儲藏室,存放指令和資料。 - 中央處理器 (CPU):電腦的大腦,負責執行指令。 - 控制器 (CU):指揮中心,解讀指令並協調各單元。 - 算術邏輯單元 (ALU):計算中心,執行數學和邏輯運算。 - 輸入設備 (Input):讓我們能對電腦下指令(如:鍵盤、滑鼠)。 - 輸出設備 (Output):讓電腦能呈現結果給我們(如:螢幕、印表機)。 ![image](https://hackmd.io/_uploads/Bk1LdpXilx.png) ### 馮紐曼瓶頸 (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)| ![image](https://hackmd.io/_uploads/HJFsq6Qsex.png) 簡單比喻: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 ``` ![image](https://hackmd.io/_uploads/r1H5vX3oex.png) 4. Base Pointer (BP) > Frame(堆疊框架) 是每次呼叫函式時,在 stack 上劃出的專屬區塊。 ![image](https://hackmd.io/_uploads/BJ7gOXnixl.png) ## 3. 權限分界:使用者模式 vs. 核心模式 為了系統的穩定與安全,CPU 有兩種運作模式,由硬體直接強制執行 。   ### 使用者模式 (User Mode / Host Code) 執行者:一般應用程式 (如 Chrome, Word, 遊戲) 。   權限:受限制。不能直接存取硬體或作業系統核心資料 。   保護:每個程式在獨立的記憶體空間執行。一個程式崩潰,不會影響到其他程式或整個系統 。   ### 核心模式 (Kernel Mode / System Code) 執行者:作業系統核心、硬體驅動程式 。   權限:最高權限。可存取所有硬體和記憶體,執行任何指令 。   風險:在核心模式下發生錯誤,會導致整個系統當機(例如 Windows 的藍白畫面)。   ### 如何切換?系統呼叫 (System Call) 當使用者模式的程式需要存取硬體時(如讀取檔案),它會發出「系統呼叫」請求,暫時切換到核心模式,讓作業系統代為處理,完成後再切換回來 。   ![user-mode-and-kernel-mode-2](https://hackmd.io/_uploads/H1Rm26Xole.png) ## 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,代表原本是關的 ```