俗諺有云:「打蛇打七寸,擒賊先擒王」。為了了解電腦的原理,通常在了解電腦的基本操作之後,想多懂一點的人,可以針對電腦的各個「器官」做深入的研究。在電腦的專門學問裡面,有一門稱為「計算機組織」(Computer Organization)的,就是在教這個事情。

而電腦裡面最重要的「器官」,首推處理器。

不過,我不是教授,各位也不是學生,只是「輕鬆但是熱切的」想要多懂一點電腦的知識而已,這專欄也不是計算機組織專業課程,所以,各位不用緊張。

但是,我們還是得學學簡單的組合語言程式,藉以了解處理器的運作原理,這和計算機組織的課程內容很類似。所不同的是,這是由筆者「不負責不專業」的觀點來介紹的,所以內容若不夠精彩、實用,還請各位請多忍耐、多包涵。

「機械運算」和「心智活動」的分離
假設今天,你要設計一臺「計算機器」,你會怎麼做?

這和數學的原理,以及機械的原理,都有一點關係。

如果算盤是中國人發明的,那這是流傳至今,最古老的計算機器。但是,嚴格說來,算盤僅是「方便你記錄數字運算過程狀態和結果」的機器,並非真的幫你計算。

因為算盤沒法自動計算。

想像一下,用算盤計算「4 + 3」怎麼做?

你撥動下方的四個算珠,代表4,然後撥動上方的一個算珠,代表5,然後去掉下方的二個算珠(因為要加3,底下的算珠不夠加,於是下5去2)。

過程中,你的「人腦」不斷運作並介入運算。算盤的好處只是幫你記錄運算過程的狀態,當你大量的運算數字時,省下你用紙筆寫數字的苦工。

如果你用算盤進行乘除,也是一樣的。有沒有辦法不會背九九乘法表,就用算盤進行乘法演算?恐怕不行。要計算「8 乘以 9」,你還是得知道「八 九 七十二」,然後用算盤記錄你演算的結果。

在我們簡單的想像中,我們可以理解到:這是一種堪用,但不夠好用的計算機器。甚至我們只能說,算盤是個計算狀態記錄器,不能算是計算機器。

只是心智活動的「模擬」而已
但製造計算機器的人們,所想要得到的,是更自動化的機器,能夠省去大量的心智活動,並仍能得到絕對精確結果的機器。

試想一下,「8 乘以 9等於72」,等一下,你有真的「把9連加8次」(或是,把8連加9次)嗎?換句話說,人類很早就知道,「心智的活動和演算的精確」可以完全無關,演算行為可以用完全機械化的方法加以得到,而且完全不損及其精確的程度。就「八 九 七十二」這個例子而言,也許你會背誦,但你完全不知道原來「八 九 七十二」其實是「把9連加8次」。問題是,你還是可以得到正確答案。

(既然提到這個,順便來談談過去幾年討論得沸沸湯湯的「建構式數學」。很多人不了解,為何建構式數學那麼的「蠢」?其實,它的目的未必是錯誤的,它僅是希望學生「徹底了解演算背後的心智活動」,而不要「鸚鵡學語似的」僅把機械演算行為背起來。不過,矯枉過正的結果,讓我們的「某一代學生」數學能力低落,因為,其實只要真正的理解演算原理之後,機械計算行為,像是九九乘法表仍是有必要的,可以簡化演算的過程。如果一步一步的演算過程每次都要重複且累加,那研究到化學「摩耳數」的時候不知道要怎辦,6.02 x 1023?加到死嗎?)

所以,為了做出這種機器,工程師發明了「處理器」這種東西。

處理器得是個,你輸入「3 + 4」,就真的可以跑出「7」這樣的機器,否則它就沒有被製造出來的意義了。但是,它的設計並不是模擬思考,它只是被設計的「像是有」心智,但是,它其實「完全沒有」。處理器只是它被設計成「3 + 4會跑出7這個答案」,但處理器「完全沒有理解力」,它只是機械而已。所以,不用幻想它會生出智慧,我想我們有生之年都看不到這種事情成真。

計算機器的誕生
一般而言,人類習慣的演算是十進位,而且為了解決各種問題,人類不斷的研究各種科學(物理、化學、數學、建築、遺傳、生理及醫學……)。但科學家很快的就發現,要設計一種「十進位的計算機器」,用「純機械的方式」是可能的,但是困難度很高。

再次強調,「可能,但困難度很高」。而且,這樣做很浪費能源,也容易失去精確度。但嚴格來說,如果你用槓桿、棍棒、水力機械、傳動皮帶、齒輪去設計電腦(或是計算機器),意義上和一臺現代電腦也沒差別就是了。只是,這樣的電腦,應該不實用。

歷史上有些成功的經驗,有些失敗的經驗,比較有名的就是「差分機」或是「分析機」,但是純機械式的設計真的太難了。所以,經過了長久的試驗,科學家最後找到的答案是:將演算變成「二進位」,並使用電子作為訊號傳遞的工具,用邏輯閘做各種演算的模擬。而製造這些邏輯閘的元件,早期使用真空管,近代則使用所謂的半導體電路。

數學家很早就發現,機械化的演算可以重複施為,只要你可以系統化的描述之。這種機械化的演算,就問題的總量上,雖然可能只占人類必須處理的問題的百分之五;但在人類常用的演算行為上,卻可能占了百分之九十五的演算份量。日常的財務計算,公司的帳目處理、國際金融的匯款……,這些都不是複雜的數學問題,但這都需要大量且精確的數字計算。

所以我們設計出電腦,來做這些工作。

早期的電腦有所謂的「中央處理器」,稱為CPU,它是電腦演算工作的核心。不過,一般人不知道的是:CPU裡面有一個稱為「暫存器(register)」的東西,暫存器則是處理器的工作核心。最早期的CPU只有一個暫存器,被稱為累積器或累加器(accumulator)。整臺電腦就利用這個累加器,進行各種演算──高速(以當時的眼光看)的演算。

處理器架構簡介
現在,CPU被稱為「處理器(Processor)」,專門進行演算的工作。為了解釋「處理器如何執行演算」,你得先知道現代處理器裡面的一般性結構:

暫存器(Register)
請注意,現代處理器裡面有大量的暫存器,它的用途就是「暫存要演算的相關資訊」。以剛才的「累加器」來講,當你要計算「3 + 4」這樣的演算時,早期電腦(處理器)的作法會是,你把「3」放進暫存器裡(處理器的設計,會使用電路設法「暫時維持住」裡面的「3」這個訊息),然後用電路進行「+ 4」的演算,再把結果(7)送到這暫存器裡面存放,這樣就完成了「3 + 4」的演算。

指令(Instruction)
印字程式範例中的「MOV」、「INC」、「LOOP」,這些就是指令。
每一個處理器,都有大量的指令,讓使用者對處理器下命令做演算。

指令能做的事情大多十分單純,以「3 + 4」這麼一個簡單的事情而言,在x86處理器上,你得用二行程式(在DEBUG裡面即可做):

MOV AX, 03
ADD AX, 04

這樣才能完成一個3 + 4的工作。MOV AX, 03=把3移動到AX暫存器(AX是x86處理器的accumulator,累加器,萬用暫存器),ADD AX, 04=把4加到AX現有的內容(也就是3)裡面。加完後,AX裡面就會有7這個結果。

組合語言(Assembly Language)
所以,學習一個處理器,就得搞懂它的結構,和它常用的指令有哪些。用這些指令和處理器裡面的結構(主要是暫存器)組合而成的程式語言,稱為組合語言。

由於每一種處理器的指令格式和內部結構,相互之間都有頗大的差距,所以組合語言是每一種處理器都不一樣的。學會了甲處理器的組合語言,到了乙處理器恐怕得重學。此外,組合語言基本上只能使用處理器相關的指令來寫程式,幾乎就像是「你直接用生物訊號控制你手腳的移動」那樣,所以組合語言也被視為是一種「低階」語言(是低階,low-level language,不是「低級」喔)。

本期結語:下期來介紹x86處理器的「專屬架構」
所以,如果我們想了解x86處理器,那我們得找一本書(或是參考資料),先研究x86的專屬架構。

什麼是專屬架構?

每一顆處理器都有屬於它的專屬架構,比方說,處理器甲有暫存器,處理器乙也有暫存器,但它們的暫存器不一定有相同的用法和名稱。

所以,我們要研究x86處理器的話,就得先熟知它的專屬架構才行。「它有哪些暫存器?」「暫存器的大部分功用是什麼?」「它有哪些指令?」「指令的格式是什麼?」「指令的功用又為何?」接下來我們得研究:「處理器怎樣完成各種特定的演算?」像是加減乘除;「處理器能處理的數值系統有哪些?」2進位、10進位和16進位的互換,或是整數、浮點數的演算。

有時我們還得研究「作業系統」的支援,像是:「怎樣用作業系統的內建功能,寫出有用的程式。」不過,這算是一個程式設計師的研究範疇就是了。我們只是藉組合語言想研究x86處理器的原理,應該不用研究到那裡,但了解一下也不壞。

不過,這些都只是「紙上談兵」,因為就算我們學完這一切,我們對於怎麼去做出處理器還是沒有概念。但這更難,這是硬體工程的研究範疇。能夠理解大致的原理我個人認為已經很夠了,更深入的了解我也沒法介紹──因為我也不懂。

我只希望,下期可以簡單又簡單的介紹一下x86的基本架構,它的暫存器有哪些,慢慢慢慢的,一步一步的介紹,我們終於就可以了解處理器的原理了。



寫個印出數字的小程式

我們可以利用Windows內建的一個叫做「DEBUG」的小工具,寫個「能印出0123456789」的DOS小程式,這程式命名為「PN.COM」。

從「開始」功能表→程式集→附屬應用程式→命令提示字元,然後在命令提示字元下,輸入DEBUG之後按下Enter。按下Enter後,畫面會出現一個「減號」的提示字元,這時你就可以在DEBUG模式下寫程式了。

輸入問號(?)可以檢查DEBUG的命令格式。

Alt+Enter可以來回切換於「全螢幕提示字元」和「視窗環境」之間。

接著請依序輸入下列幾行字,這就是「從0印到9」組合語言程式碼。不過第一行的A100不是程式,而是用DEBUG寫程式的宣告。程式第一行是從「MOV CX, 0A」開始:

A100
     MOV CX, 0A
     MOV AH, 02
     MOV DL, 30
     INT 21
     INC DL
     LOOP 0107
     INT 20

注意,最後一行程式是INT 20,輸入完畢之後再按一次Enter就可以結束輸入程式。

要執行程式只需要輸入G然後按下Enter,即可看到印出的文字(0~9)出現在下方。

要儲存程式,則請依據下列步驟(假設程式要取名為PN.COM,意指「Print Number」):

RCX
010F
N PN.COM
W

輸入「Q」,即可結束DUBUG的執行。

在DOS命令列下,只要輸入PN,程式就會再次印出0~9的數值。

熱門新聞

Advertisement