本附錄收錄暫存器機器(register machine)習題的解答。這些練習使用 RAP 程式(RAP program,即暫存器組合程式設計)來操作暫存器機器——一種只會做「遞增(increment)」「遞減(decrement)」與「條件跳躍」的極簡計算裝置。透過親手推演這些程式,讀者能體會最基本的計算如何從幾條笨拙的規則堆疊而成。
這些習題對應正文中關於暫存器機器的章節。若你尚未讀過相關內容,本附錄的解答會顯得抽象;建議搭配原練習的流程圖(flow graph)一起參看。
練習一:程式一的步數#
以「程式一」執行加法,計算所需步數(把 End 也算作一步)。

圖 1:練習一「程式一」的加法流程圖(α 進入暫存器 1 的遞減節點 −1,非零時跳到 +2 遞增,歸零時分支到 End Ω)
- a. 計算 2 + 5 = 7 需要幾步? 答:六步。三次遞減、兩次遞增、一次 End(最後一次遞減是「歸零時分支」)。
- b. 計算 5 + 2 需要幾步? 答:十二步。六次遞減、五次遞增、一次 End。
從 a、b 兩題可得出關鍵結論:運算元的順序會造成很大的步數差異。你或許會想訂一條規則——永遠把較小的數放進暫存器 1。但別忘了:若要先「測試」兩個數哪個較小,光是這個比較就會用掉比直接做加法還多的步數。優化本身也有成本,有時得不償失。
練習二:減法程式與防呆設計#
- a. 依流程圖寫出對應的 RAP 程式。由於程式含有分支,步驟可以有多種編號方式;只要「go to」指令都指向正確的步驟,怎麼編號都無所謂。

圖 2:練習二 減法程式的註解流程圖(依序初始化答案暫存器與符號暫存器、執行相減、修正暫存器 2、置入負號旗標,最後把答案搬到暫存器 4)

圖 3:練習二 減法程式對應的 RAP 指令表(約十一個步驟)
- b. 當程式試圖算 3 − 3 或 4 − 4 時會發生什麼? 程式停機(halt),暫存器 4 中留下 0。
- c. 為什麼要在步驟 3 做減法「之前」把暫存器 3 歸零,而不是在步驟 4「之後」?這樣防止了什麼錯誤? 若一開始暫存器 1 與暫存器 2 中都是 0,程式結束時可能得出無意義的答案——例如「−0」,或符號暫存器(sign register)裡出現 0 與 1 以外的怪數字。事先歸零可避免這種殘留狀態污染結果。
練習二 c 點出程式設計中反覆出現的陷阱:初始狀態的殘值。不先清乾淨暫存器就開始運算,邊界情況(如兩者皆為 0)就會冒出你意想不到的輸出。歸零的時機(先做還是後做)直接決定了程式是否正確。
練習三:乘法器#
- a. 畫出流程圖並寫出 RAP 程式,將暫存器 1 的內容乘以暫存器 3 的內容,答案放進暫存器 5。

圖 4:練習三 a 題 乘法器的流程圖(把暫存器 1 的內容乘以暫存器 3 的內容,答案累加進暫存器 5)

圖 5:練習三 a 題 乘法器對應的 RAP 指令表(約九個步驟,含歸零暫存區與「反覆把暫存器 1 加到自身」的倒數累加)
以下兩題為選做,重點在於「不破壞輸入」這個更高的要求。
選做延伸:改良乘法器(b、c 題)
- b.(選做) 運用 Copy 與 Move 指令改良 a 題的乘法器:程式停止時,暫存器 1 與暫存器 3 的原始內容都被還原,如此一來,執行後就能輕鬆核對輸入與輸出是否正確。

圖 6:練習三 b 題 改良乘法器的大型流程圖(先複製暫存器 1 與暫存器 3 的內容,再套用 3a 的乘法子程式,最後把原始內容還原回暫存器 1 與 3)

圖 7:練習三 b 題 改良乘法器對應的 RAP 指令表(約二十四個步驟)
- c.(選做) 畫出流程圖並寫出 RAP 程式,檢查暫存器 1 與暫存器 3 的內容(不得破壞它們!),把「內容較小者」的位址(1 或 3)寫進暫存器 2;若兩者相等,則在暫存器 2 中放入 2。 換言之,程式執行後:暫存器 1 與 3 的內容不變,而暫存器 2 會告訴你兩者是否相等,若不等則指出哪一個暫存器的內容較小。

圖 8:練習三 c 題 比較流程圖(不破壞地把暫存器 1 與 3 的內容複製出來相減,依「相等/較小」的三種結果把較小者位址寫入暫存器 2)

圖 9:練習三 c 題 比較程式對應的 RAP 指令表(約二十四個步驟,含相減比較與寫入暫存器 2)
這兩題的共通挑戰在於:暫存器機器的基本操作(遞減)本身就是破壞性的,要「讀取而不消耗」內容,就必須先把內容搬走再搬回,藉此重建原狀態。
練習四(選做):把暫存器機器變成口袋計算機#
畫出流程圖並寫出 RAP 程式,讓暫存器機器化身為一台簡易口袋計算機:
- a. 用暫存器 2 指定運算:
- 0 = 加
- 1 = 減
- 2 = 乘
- 3 = 除
- b. 把要運算的數值放進暫存器 1 與暫存器 3。
於是輸入可用三位數表示(運算碼、運算元、運算元):
- 306 代表 3 + 6
- 513 代表 5 − 3
- 425 代表 4 × 5
- 933 代表 9 ÷ 3
輸出則放進暫存器 4 到 7:
- 暫存器 4:符號(0 為 +,1 為 −)
- 暫存器 5:數值答案
- 暫存器 6:除法時的餘數
- 暫存器 7:警示燈,標示「除以零」的錯誤

圖 10:練習四 口袋計算機的完整流程圖(以暫存器 2 的運算碼分派到加法、減法、乘法、除法四段子程式,並在除法段檢查除以零)

圖 11:練習四 口袋計算機 RAP 指令表的前半(步驟約 1–29,涵蓋運算碼分派與加、減、乘及除法起始)

圖 12:練習四 口袋計算機除法部分的 RAP 指令表(步驟約 30–37,含除以零錯誤旗標與還原暫存器 3)
練習四把前面各題的零件組裝成一台功能完整的小機器:以暫存器 2 當「指令解碼器」分派四種運算,再以暫存器 7 當「例外處理」攔截除以零。這正是一切計算機的縮影——簡單的原子操作,經由分支與狀態的層層堆疊,就能長出看似複雜的功能。