學習筆記:指令格式 (Computer Science 9645)
歡迎進入機器碼的世界!
你好!這一章是你理解電腦核心運作的關鍵。我們將超越像 Python 這樣的高級程式語言,深入了解中央處理器(CPU)真正能讀懂的原始語言:機器碼 (Machine Code)。別擔心,這聽起來可能很複雜,但我們會拆解每個電腦指令的藍圖:指令格式 (Instruction Format)。
理解指令格式至關重要,因為它解釋了:
- 像「將 5 加到暫存器 R1」這樣簡單的指令是如何翻譯成一系列位元(bits)的。
- 電腦如何知道「執行什麼操作」以及「在哪裡找到所需的數據」。
第一部分:處理器指令集 (Processor Instruction Set)
當你撰寫程式時,CPU 需要確切知道它可以執行哪些動作。這份有效動作的清單稱為處理器指令集 (Processor Instruction Set)。
什麼是指令集?
指令集是特定 CPU 能夠理解並執行的所有指令(命令)的完整集合。你可以把它想像成 CPU 的字典和詞彙表。
- 從基本的算術運算(加、減)到記憶體存取(載入、儲存),每個指令都在這個集合中定義。
處理器的專有性
非常重要的一點是,指令集是處理器專有的 (processor specific)。這意味著:
- Intel CPU(許多桌上型電腦所使用)使用的指令,與 ARM CPU(常見於智慧型手機)使用的指令是不同的。
- 如果你使用處理器 A 的指令集編寫程式,它通常無法直接在處理器 B 上執行,除非處理器 B 被設計為能模擬(emulate)處理器 A。
重點總結:CPU 的語言(指令集)對於該類型的處理器來說是獨一無二的。
第二部分:指令的剖析
每一個指令(無論是機器碼還是組合語言)都遵循特定的格式。它必須包含三個基本組成部分:
- 運算碼 (Opcode / Operation Code)
- 定址模式 (Addressing Mode)
- 運算元 (Operand(s))
比喻:食譜指令
你可以把一個指令想像成食譜中的一個步驟:
「攪拌 (Mix) (運算碼),直接 (Directly) (定址模式) 使用 標示為『材料』的碗 (bowl labeled 'Ingredients') (運算元) 中的內容。」
1. 運算碼 (Opcode - Operation Code)
運算碼告訴 CPU 要做什麼操作。
- 它是指令的功能,例如 ADD(加)、SUBTRACT(減)、LOAD(載入)或 STORE(儲存)。
- 在機器碼中,運算碼由特定的位元模式表示(例如,0010 可能代表 ADD)。
2. 運算元 (Operand(s))
運算元指定指令應該對什麼數據進行操作,或者去哪裡找這些數據。
運算元可以是以下三者之一:
- 數值 (Value)(數據本身,例如數字 5)。
- 記憶體位址 (Memory Address)(RAM 中的某個位置)。
- 暫存器 (Register)(CPU 內部的一個小型高速儲存位置)。
3. 定址模式 (Addressing Mode)
定址模式告訴 CPU 如何解讀運算元——運算元是指數據本身,還是一個位置?
機器碼指令的格式(位元的佈局與大小)會根據指令類型而有很大差異(例如,一個簡單的 HALT 停止指令可能只需要運算碼,而複雜的計算則需要運算碼、定址模式和多個運算元)。
指令 = 運算碼(做什麼)+ 定址模式(如何找到數據)+ 運算元(數據或位置)。
第三部分:指令的表示方式
我們需要兩種方式來表示指令:一種給機器看,一種給我們人類看。
機器碼 (Machine Code / Binary)
在其原始形式中,機器碼完全以二進制 (binary)(0 和 1 的序列)表示。
- 這是最低級的語言;可以直接由 CPU 執行。
- 範例:0010 0101 00001010(這可能代表:ADD,立即定址,數值 10)。
組合語言 (Assembly Language / Mnemonics)
組合語言使用助記符 (mnemonics)——即短小、人類可讀的代碼——來代表機器碼指令。
- 對於程式設計師來說,助記符比冗長的二進制字串更容易閱讀和編寫。
- 範例:ADD #10, R5
你知道嗎?CPU 無法直接理解助記符。它們必須由一種稱為組譯器 (Assembler) 的軟體翻譯成二進制的機器碼。
重點總結:機器碼是二進制(0s/1s);組合語言使用助記符(如 ADD, LOAD, STORE)。
第四部分:理解定址模式(關鍵!)
定址模式決定了 CPU 如何解讀運算元欄位以找到所需的數據。課程大綱要求你理解並應用三種主要類型。
1. 立即定址 (Immediate Addressing)
在立即定址中,運算元欄位就是實際的數值 (data),直接供指令使用。
比喻:冰箱上的便條紙
如果你告訴某人:「數值是 5」,你不需要告訴他們去哪裡找,因為你已經直接給了他們這個數值。
- 運作方式:指令本身直接包含了數值。
- 用途:將常數或立即數載入暫存器。
- 範例 (組合語言):
LOAD #5, R1(將數值 5 載入暫存器 R1)。「#」符號通常表示立即定址。
2. 直接定址 (Direct Addressing)
在直接定址中,運算元欄位就是位址 (address/location),可以在該處找到數據。
比喻:信箱編號
如果你告訴某人:「去 100 號位址找那個數值」,他們必須前往位置 100 才能取出物品。
- 運作方式:CPU 將運算元解讀為主記憶體位址或暫存器編號。然後它會前往該位置提取數據。
- 用途:存取儲存在記憶體中的變數。
- 範例 (組合語言):
LOAD 100, R1(將儲存在記憶體位址 100 的值載入暫存器 R1)。
3. 間接定址 (Indirect Addressing)
在間接定址中,運算元欄位指定一個暫存器,而該暫存器儲存了主記憶體中數據的實際位址。
這是一個兩步驟的過程:
- 查看運算元以找到暫存器編號 (R_X)。
- 前往 R_X 找到記憶體位址 (A)。
- 前往記憶體位址 (A) 找到實際數據。
比喻:索引卡片
有人告訴你:「看看那個信封(暫存器 R1)。信封裡面有一張紙,上面寫著『位址 500』。現在去位址 500 找那個物品。」
- 運作方式:運算元指向一個暫存器,該暫存器間接地指向所需的記憶體位置。
- 用途:對於遍歷陣列或複雜的資料結構非常有用,因為儲存位址的暫存器可以輕鬆地進行遞增(增加)。
- 範例 (組合語言):
LOAD (R2), R1(括號表示間接定址。將儲存在暫存器 R2 內的記憶體位址中所對應的值,載入到暫存器 R1 中)。
定址模式比較
| 模式 | 運算元包含... | 獲取數據的步驟 |
|---|---|---|
| 立即定址 | 數值本身 | 0 步(數據直接提供) |
| 直接定址 | 數據的位址(在記憶體或暫存器中) | 1 步(直接前往該位址) |
| 間接定址 | 一個儲存數據位址的暫存器 | 2 步(先去暫存器,再去記憶體位址) |
重點總結:掌握這三種定址模式(立即、直接、間接)對於理解指令如何定位數據至關重要。