現代的電腦無論其運算速度如何,只要是單一處理器(CPU,Central Processing Unit),都可以用下面的圖形來說明其基本架構, 至於多處理器電腦系統本文不予討論 。
各部分的功能如下所述:
Memory(記憶體): 可分成很多個小格子,每個格子都可存放一筆資料。有時也可稱為Main Memory(主記憶體)
I/O interface(輸出入介面): 是電腦和外界的窗口,可以從外界輸入(Input)資料,或將資料輸出(Output)到外界。常見的輸入裝置如鍵盤,滑鼠;常見的輸出裝置如螢幕,印表機。
Control Unit(控制單元): 負責指令的擷取和解釋
ALU(Arithmetic and Logic Unit, 算數與邏輯單元): 負責算數與邏輯指令的實際執行工作,裡面有一些記憶體供計算所需,特別稱為Register(暫存器)。暫存器的數量隨硬體而不同,此處說明用的虛擬電腦只有一個暫存器。 一般常見的暫存器則有
在上圖的機器中共有100個記憶體可用,每個記憶體可以存放3個數字。Control Unit, ALU, Program Counter在現代的硬體設計裡多做在一起,稱為CPU(Central Processing Unit)。Pentium 4就是Intel這家公司的CPU產品。
電腦執行一個機器指令的步驟為:
Fetch(擷取指令): 由Control Unit讀取Program Counter的內容,根據Program Counter的數值去相對應的Memory抓指令
Decode(解碼): 抓到的指令經Control Unit判讀,決定要如何執行該指令
Execute(執行): 在ALU(Alrithmetic and Logic Unit)裡執行該指令
Write(寫回): 更改Program Counter的內容
虛擬機器的指令集
不同的CPU其設計的指令集也不同,最常見的x86系列CPU(Pentium 4即屬於該系列),其指令集包括幾百個指令。一般而言,電腦指令可以分類為下面幾類:
資料複製: 將暫存器的複製到主記憶體(STORE),將主記憶體複製到暫存器(LOAD)
算數運算: 如加減乘除
邏輯運算: 判斷條件是否成立,如大於,小於,等於
更改Program Counter
輸出入
為說明起見,我們定義以下的虛擬機器指令集:
虛擬機器的指令的格式:由3個數字組成,第一個數字代表指令,後面兩個數字代表記憶體的地址。機器指令執行時會改變某些記憶體(含Program Counter以及暫存器等CPU內部的記憶體,以及Main Memory)的內容,而這些記憶體就決定了指令執行的結果。換句話說,電腦不記得過去,也不知道未來,他只能透過記憶體的內容知道現在的情況。
指令0--LOAD XX
將XX記憶體的內容複製到暫存器內,然後將Program Counter加1
指令1--STORE XX
將暫存器的內容複製到XX記憶體,然後將Program Counter加1
指令2--ADD XX
將記憶體XX的內容與暫存器內的數值相加,結果放在暫存器上,然後Program Counter加1
指令3--SUB XX
將暫存器內的數值減掉記憶體XX的內容,結果放在暫存器上,然後Program Counter加1
指令4--JUMP XX
將Program Counter的內容改為XX
指令5--SKIP
若暫存器的內容>=0,則把Program Counter+1,否則把Program Counter+2
指令6--INPUT
由輸入裝置讀入資料放到暫存器上,然後將Program Counter+1
指令7--OUTPUT
由暫存器將資料送到輸出裝置,然後Program Counter +1
指令8--CALL XX
將(Program Counter+1)放到堆疊上,然後Program Counter的內容改成XX
指令9--RETURN
由堆疊上取出一個數值,然後將Program Counter的內容改成此數值
指令10--HALT
程式停止執行
附註:
所謂堆疊(Stack)是一個上方只有一個開口的容器,當要把資料放入堆疊時,是放在堆疊的最上面,當要從堆疊拿資料時,是從最上面拿。放入的動作稱為push,拿出來的動作稱為pop。 由於只有一個開口,你可以觀察到先放進去的資料會最後拿出來(Firt In Last Out,FILO).例如依序push 1,2,3,4四個數字,然後再pop四次,你會發現拿出來的順序是4,3,2,1 。只要符合FILO特性的容器,就可稱為堆疊。電腦內部的Stack是用Main Memory來模擬的。
以下是以虛擬機器語言所寫的兩數字相加程式,--後面的部分是註解,是給人看的,電腦不予處理:
INPUT -- 輸入數字到暫存器,program counter+1
STORE 99 -- 將暫存器的內容複製到記憶體99的地方,program counter+1
INPUT -- 輸入數字到暫存器,program counter+1
ADD 99 -- 將記憶體99的內容加到暫存器,program counter+1
OUTPUT -- 將暫存器的內容輸出,program counter+1
HALT -- 程式停止執行
計算abs(x-y)
INPUT -- 輸入數字到暫存器,program counter+1
STORE 98 -- 將暫存器的內容複製到記憶體98的地方,program counter+1
INPUT -- 輸入數字到暫存器,program counter+1
STORE 99 -- 將暫存器的內容複製到記憶體99的地方,program counter+1
SUB 98 -- 將暫存器的內容減掉記憶體98的內容,program counter+1
SKIP -- 如果暫存器的內容>= 0則program counter+1;否則program coounter+2
JUMP 9 -- 將program counter設為9,也就是跑到第9行的OUT指令
LOAD 98 -- 將記憶體98的內容複製到暫存器,program counter+1
SUB 99 -- 將暫存器的內容減掉記憶體99的內容 ,program counter+1
OUTPUT -- 將暫存器的內容輸出, program counter + 1
HALT -- 程式停止執行
呼叫函數將兩個數字相加的範例
INPUT -- 輸入數字到暫存器,program counter+1
STORE 99 -- 將暫存器的內容複製到記憶體99,program counter+1
INPUT -- 輸入數字到暫存器,program counter+1
STORE 98 -- 將暫存器的內容複製到記憶體98,program counter+1
CALL 07 -- 將program counter+1(也就是5)放到堆疊上 ,program counter改為07
OUTPUT -- 將暫存器的內容輸出, program counter + 1
HALT -- 結束程式
LOAD 99 -- 將記憶體99的內容複製到暫存器上,program counter+1
ADD 98 -- 將暫存器的內容加上記憶體98的內容,program counter+1
RETURN -- 由堆疊取出一個數值(目前最上面的為5),並將program counter設為該數值
Software development process
撰寫程式的流程如下圖,所需要的工具包括Text Editor,Preprocessor,Compiler,Linker等四種
Text Editor:程式設計師利用此工具編輯(Edit)Source code file(Text Format), 也就是說產生.c檔的工具。
Preprocessor:結合Source code file(.c檔)和零到多個Header files(.h檔),經過編輯(Edit)後成為另一個修改過的Source code file。
Compiler:將source code編譯(compile)產生Object code file(.o檔, Binary Format),同一個作業平台的Object code格式相同,也就是說Object code file可以由不同程式語言的Compiler產生。
Linker:將幾個Object code files連結(link)產生一個可執行檔(.exe檔)。
如果你的開發環境是在Windows上,下面有關vi和gcc的說明可以跳過。
在Unix作業系統內,最常見的Text Editor是vi。
Preprocessor,Compiler和Linker可以是三個不同的程式,也可以包成一個。Unix作業系統上最常見的C語言開發環境是gcc(GNU C Compiler),他把Preprocessor,Compiler和Linker三個功能合在一起以方便使用。最簡便的用法是:
gcc hello.c
若hello.c完全沒有錯誤,則以上命令會產生一個執行檔a.out,在命令列下打a.out即可觀察你所寫程式的執行結果。有時候若你設定的環境變數不對,則可能出現Command Not Found的錯誤,此時你可輸入./a.out。若不想讓gcc編譯出來的執行檔叫做a.out,則可下達以下命令:
gcc -o exename hello.c
撰寫大型程式時,很可能會有多個.c的原始程式檔,假設他們的名稱是source1.c, source2.c, source3.c...如果要個別編譯這些source code,則下達如下命令:
gcc -c source1.c
若編譯成功,會產生source1.o的檔案。要將數個Object Code連結成為一個可執行檔,則下達以下命令:
gcc source1.o source2.o source3.o
至於Windows作業系統上的程式編寫環境,最常使用的是Microsoft Visual Studio,裡面就包含了Visual C++的開發環境。因為C++可視為C語言的父集合,因此你也可以用Visual C++來開發C程式。這類視覺化的開發工具(Dev C++也是其中一種),已經把Text Editor, Preprocessor, Compiler, Linker整合在一起, 並包括Project Management(專案管理)等功能, 因此這類工具又稱為Integrated Development Environment(IDE,整合開發環境)。