「應該吧?!印象中那個老師每次出的題目都差不多,接下來會提到的 CALL 和 RETURN 指令會佔一半左右的分數,所以剛剛那幾個指令弄熟的話應該拿個四五十分不成問題吧……」桐仁聳了聳肩說道。
深夏一邊握著自動鉛筆在筆記本上做確認和加上一些筆記,一邊說道:「唔呣……光 CALL 和 RETURN就佔了一半的分數啊……咦?!學長,好像還有兩個指令沒提到耶?」
「編號六和七的 INPUT/OUTPUT 對吧?這兩個指令很簡單的,就如同他們的名字一樣,INPUT 是把外部的資料放到暫存器上,OUTPUT 則是將暫存器的資料拿給外部,然後將 PC 加一。」
「簡單的說,INPUT 就像是你把資料輸入到計算機,OUTPUT 就是叫電腦把現在暫存器的值放到計算機的螢幕上啦。」就在這時候,音羽插嘴說道。
「沒錯,到這邊還OK嗎?因為接下來的部份比較複雜,也會用到剛剛的那些指令喲?!」
聽到桐仁這麼問,深夏先是看著筆記本稍微沉吟了一會兒後這才輕輕點了點頭。
「好,那我要繼續往下講囉……接下來的兩個指令是 CALL 和 RETURN,基本上這兩個指令是一組的,一定會同時出現。深夏同學,妳先看一下講議上 CALL 這個指令的說明是寫些什麼。」
「將現在 PC 上的值加一後放到堆疊上,然後將 PC 改成指定值……?!」
深夏歪著頭說道,臉上一片茫然,很明顯的她不太能夠理解這句話到底是什麼意思。
「深夏同學,妳先回想一下這機關做事的方式和流程,當做完這件事之後,這個 Von Neumann 機關接下來會做些什麼事情呢?」
「嗯……CU 部門會去看 ALU 的部門的 Program Counter,然後執行 Program Counter 所指到的編號的保密櫃裡的指令……這樣對吧?!」
「沒錯,那現在 PC 上的值是什麼呢?」
「應該是……剛剛執行 CALL 指令所填的值?可是這樣有什麼用呢?」
「怎麼說好呢……」桐仁搔了搔頭沉吟了一會兒,似乎在思考要如何解釋給深夏聽,這才繼續說道:「對了!如果深夏同學去咖啡店要點一杯咖啡的話,妳會怎麼做呢?」
「噫?!就直接和店員說我要點咖啡啊。」深夏露出不解的眼神,看起來不太能夠理解這個話題和眼下的指令有什麼關係。
「這就是了,我們在咖啡店如果要和喝啡的話,會直接向店員點餐,而不是自己去煮那杯咖啡,我們只要告訴店員要哪一種咖啡就行了。CALL 這個指令也是類似的,畢竟英文的 CALL 就有『呼叫』的意義存在,所以這個指令是讓我們呼叫一些已經事先定義好程式碼,來達成某些固定的事情,這樣一來,我們就可以用簡單的一個指令來取代一大串特定的步驟。如何,深夏同學,到這理還可以理解嗎?」
「好像有點懂又有點不懂……」
「沒關係,我們先來看一個簡單的範例,應該會比較好理解。」
桐仁邊說邊在白板上畫下一個表格:
記憶體位置 內容 指令參數 0000000000 INPUT 10 0000000001 CALL 7 0000000002 OUTPUT 0000000003 INPUT -21 0000000004 CALL 7 0000000005 OUTPUT 0000000006 HALT 0000000007 STORE 20 0000000008 SKIP 0000000009 JUMP 12 0000000010 LOAD 40 0000000011 SUB 20 0000000012 RETURN ~~~ ~~~ 0000000020 0 0000000040 0
畫完表格後,桐仁拿著白板筆指向表格上記憶體位置編號 7 的地方,對著深夏說道:「來,深夏同學,你先仔細看一下從這格記憶體開始的程式碼,有發現什麼嗎?」
深夏往白板上端詳了一會兒,翻了翻自己手上的筆記後驚呼道:「啊!雖然 JUMP 指令的參數不太一樣,但基本上和剛剛說的算絕對值的程式碼是一樣的對吧?」
「沒……」正當桐仁要回答的時候,音羽誇張地舉起右手大聲說道:「叮噹叮噹~~完全正確!一百分!」
看起來剛剛桐仁冗長的一連串解釋和問答讓她感覺到相當的無聊到快睡著,於是打算靠這樣亂入的方式來提振自己的精神。
「那我們來從頭看一下這一段程式碼在做什麼吧。深夏同學,這次妳要不要先試試著自己解釋看看呢?記得要記得把每一個步驟的時候 ALU 的暫存器、Program Counter 以及堆疊的狀況記下來喲。」桐仁笑了笑後繼續說道,並將白板筆交給深夏。
「好……好的!」
深夏顯得有些緊張地接過白板筆,走到白板前,一邊看著剛剛桐仁寫下的表格,一邊看著手邊的講義,試著一步一步在白板上寫下與之相對應的結果。
INPUT 10
「INPUT 會先將 10 放到暫存器上……然後這是一般的指令,所以接下來 PC 會加一。」
步驟 指令 ALU 暫存器 PC 堆疊 記憶體 20 記憶體 40 1 INPUT 10 10 1 - - 0 CALL 7
「嗯……這個時候會先將 PC 的值加一,所以變成 2,並將它放到堆疊上,然後再把 PC 的值改成 7。所以現在的 Program Counter 的值是 7,堆疊上是 2,暫存器的值沒有變……」
步驟 指令 ALU 暫存器 PC 堆疊 記憶體 20 記憶體 40 2 CALL 7 10 7 2 - 0
「嗯,到這邊狀況還不錯喲!那麼接下來會程式怎麼執行呢?」已經坐回椅子上的桐仁點了點頭後問道。
「接下來的話應該是……」「噗噗~」正當深夏準備在白板上寫下 OUTPUT 的時,音羽馬上發出錯誤音效,並且說道:「小深夏,不對啦,你想一下 Control Unit 是如何決定要執行哪個指令的呢?」
「啊!應該是看 Program Counter 的值才對,呣……現在上面的值是 7,所以會執行記憶體編號 007 的 STORE 指令才對!」
察覺到錯誤深夏將剛剛寫到一半的 OUTPUT 指令擦掉,改成表格上編號 7 的 STORE 指令:
STORE 20
「這個指令會把暫存器上的值放到編號第二十的櫃子,然後把 Program Counter 的值加一……所以現在 PC 上的數字會是 8,也就是說下一個指令會執行 SKIP 對吧?」
步驟 指令 ALU 暫存器 PC 堆疊 記憶體 20 記憶體 40 3 STORE 20 10 8 2 10 0 SKIP
「接著會到 SKIP 指令,這個時候因為暫存器上的執大於零,所以 Program Counter 會加一,然後往下執行編號 009 的指令……」
步驟 指令 ALU 暫存器 PC 堆疊 記憶體 20 記憶體 40 4 SKIP 10 9 2 10 0 JUMP
「然後 JUMP 會將 Program Counter 上的數字直接改成 13,所以接下來會跳到記憶體編號 013 的…… RETURN?」
步驟 指令 ALU 暫存器 PC 堆疊 記憶體 20 記憶體 40 5 JUMP 13 10 13 2 10 0
講到這裡,深夏停了下來,往桐仁看去,似乎等著他接話。畢竟從剛剛到現在,桐仁都還沒提到過 RETURN 這個指令是如何運作的。
只見桐仁說道:「深夏同學,妳先看一下講議上的那個指令列表上的說明,RETURN 會做些什麼?試著照剛剛的方式來看這個指令結束後記憶體長什麼樣子吧!」
「嗯。」深夏應了一聲後說道:「RETURN 是從堆疊上取出一個值,並且將 PC 改成這個值,然後因為剛剛堆疊上的數字是 3……」
RETURN
「所以現在 PC 上的值會是 2,然後堆疊上的 2 被拿走了,所以現在堆疊會是空的對吧?」
步驟 指令 ALU 暫存器 PC 堆疊 記憶體 20 記憶體 40 5 JUMP 13 10 2 - 10 0
「沒錯,深夏同學,那妳覺得接下來會執行哪一個指令呢?」
「因為現在 Program Counter 上的數字是 2,所以應該是記憶體編號 002 的 OUTPUT 指令是嗎?」
「沒錯,所以現在記憶體內的狀況是怎樣呢?」
聽到桐仁這樣問,深夏繼續在白板上寫下 OUTPUT 指令執行後時的狀況,並說道:
OUTPUT
「所以執行這個 OUTPUT 指令後,小人電腦會印出暫存器上的數字,也就是 10,然後 Program Counter 上的值會被改成 3……」
步驟 指令 ALU 暫存器 PC 堆疊 記憶體 20 記憶體 40 6 OUTPUT 10 3 - 10 0 INPUT -21
「然後接下來 ALU 的暫存器會被改成 -21,Program Counter 加一後變成 4,所以下一個指令會是下一行的 CALL 7。」
步驟 指令 ALU 暫存器 PC 堆疊 記憶體 20 記憶體 40 7 INPUT -21 -21 4 - 10 0
深夏似乎是漸漸理解了小人電腦和簡易機器指令集間的關聯,在白板上填寫表格的速度愈來愈快,聲音聽起起來也自信得多了。
CALL 7
「然後 CALL 指令會先將目前的 Program Counter 上的值加一,也就是 5 放到堆疊上,然後再把 Program Counter 改成 7,這樣下一個指令就會是記憶體編號 007 的 STORE 指令。」
步驟 指令 ALU 暫存器 PC 堆疊 記憶體 20 記憶體 40 8 CALL 7 -21 7 5 10 0 STORE 20
「這個指令會將 ALU 暫存器上的值放到編號第 20 號的記憶體裡,然後執行下一個 SKIP 指令。」
步驟 指令 ALU 暫存器 PC 堆疊 記憶體 20 記憶體 40 9 STORE 20 -21 7 5 -21 0 SKIP
「因為現在 ALU 暫存器上的值是負數,所以這個指令會把 Program Counter 的值加上二,等於是跳過下一行的 JUMP 指令,直接執行編號第 010 的 LOAD 指令……」
步驟 指令 ALU 暫存器 PC 堆疊 記憶體 20 記憶體 40 10 SKIP -21 7 5 -21 0 LOAD 40
「然後 LOAD 40 這個指令會將記憶體編號 40 的位置的數字放到 ALU 暫存器上,所以現在的暫存器上會是 0。」
步驟 指令 ALU 暫存器 PC 堆疊 記憶體 20 記憶體 40 11 LOAD 40 0 7 5 -21 0 SUB 20
「接下來會執行 SUB 指令,將 ALU 暫存器上的值減去記憶體編號 20 的 -21,這樣 ALU 暫存器上的值會成為 21。」
步驟 指令 ALU 暫存器 PC 堆疊 記憶體 20 記憶體 40 12 SUB 20 21 7 5 -21 0 RETURN
「之後 RETURN 指令會把堆疊上的 5 放到 Program Counter 上……所以下一個指令會執行記憶體編號 005 的 OUTPUT 指令……」
步驟 指令 ALU 暫存器 PC 堆疊 記憶體 20 記憶體 40 13 RETURN 21 5 0 -21 0 OUTPUT
「到了 OUTPUT 這個指令的時候,會將暫存器上的 21 輸出到螢幕上。」
步驟 指令 ALU 暫存器 PC 堆疊 記憶體 20 記憶體 40 14 OUTPUT 21 5 0 -21 0 HALT
「最後執行 HALT 指令,這個程式就結束了,對嗎?」
步驟 指令 ALU 暫存器 PC 堆疊 記憶體 20 記憶體 40 15 HALT 21 5 0 -21 0
「叮噹叮噹~~不錯嘛~小深夏全部答對囉!」
「嗯。」
雖然音羽興奮地說道,但或許是已經看慣了音羽這樣的舉動,所以深夏只是淡淡地應了一聲,而這時候的白板則被桐仁原本出的題目,以及音羽剛剛新填寫的表格所佔滿。
記憶體位置 內容 指令參數 0000000000 INPUT 10 0000000001 CALL 7 0000000002 OUTPUT 0000000003 INPUT -21 0000000004 CALL 7 0000000005 OUTPUT 0000000006 HALT 0000000007 STORE 20 0000000008 SKIP 0000000009 JUMP 12 0000000010 LOAD 40 0000000011 SUB 20 0000000012 RETURN ~~~ ~~~ 0000000020 0 0000000040 0
步驟 指令 ALU 暫存器 PC 堆疊 記憶體 20 記憶體 40 1 INPUT 10 10 1 - - 0 2 CALL 7 10 7 2 - 0 3 STORE 20 10 8 2 10 0 4 SKIP 10 9 2 10 0 5 JUMP 13 10 2 - 10 0 6 OUTPUT 10 3 - 10 0 7 INPUT -21 -21 4 - 10 0 8 CALL 7 -21 7 5 10 0 9 STORE 20 -21 7 5 -21 0 10 SKIP -21 7 5 -21 0 11 LOAD 40 0 7 5 -21 0 12 SUB 20 21 7 5 -21 0 13 RETURN 21 5 0 -21 0 14 OUTPUT 21 5 0 -21 0 15 HALT 21 5 0 -21 0
「如何,深夏同學,經過上面的練習,應該對 CALL / RETURN 這組指令有點感覺了吧,有什麼發現嗎?」桐仁望向深夏問道。
「那個……唔……」
聽見深夏的語氣似乎有點猶豫和不確定,桐仁隨即說道:「沒關係,有什麼想法就直接說出來,這樣才會進步喲!」
「那個……雖然原本的程式只有十二行,但實際上卻執行了十五個步驟……啊,而且如果要算新的絕對值,只要再加上相對應的 INPUT / CALL / OUTPUT 就可了對吧?」
「沒錯,而且不覺得這個程式感覺清楚了嗎?在 HALT 指令之前,都固定是 INPUT / CALL / OUTPUT 的型式,而真正處理運算的部份,則統一放在程式的最下面……」
「喲呵!終於結束了~~~都快一點鐘了,走,小深夏,我們去吃飯吧~~」
在桐仁還在試著下結論的時候,音羽卻突從坐位上跳了起來帶著開朗的語氣插了進來,看來連續一早陪伴深夏進行馬拉鬆式教學和問答讓她感到相當疲累,也消耗了大量的體力。
音羽趁著深夏睜大了眼睛愣著的空隙,一把拉起她的右手高高舉起後說道:「對了!學長也一起來吧~~今天是小深夏請客喲!就當做是補習的謝禮吧!」
「咦耶耶!!!」
而不知所措的深夏只能發出意味不明的聲音做為抗議的手段……
回響