1. 程式人生 > >CPU的組成結構及其原理(一)

CPU的組成結構及其原理(一)

中央處理器(Central Processing Unit, CPU)

CPU的基本架構和工作原理其實百科上講得已經相當清楚了,不過我覺得有些事情呢還是給個例子出來比較方便學習。
本文會先從記憶體地址,計算機的一般架構之類的基礎知識出發,然後逐步為讀者“拼裝”出一個超級簡單的8-bit CPU。。。就像下圖這樣(大圖點開)

這就是本文的目標:拼裝這樣一個結構的CPU

-----------------------------------------------------------------------------------------------------------------------

上面那個大圖裡有幾個梯形的符號
它們叫做資料選擇器(Multiplexer),也叫多路選擇器或多路開關
已經知道這個東西是幹啥的童鞋直接跳過此樓吧。。

這圖是一個2選1選擇器,A,B,S為輸入,Z為輸出,它們可取的值當然都只有0和1
怎麼工作的呢?
以該圖為例:
當S=1的時候,輸出值Z = 輸入值B
當S=0的時候,輸出值Z = 輸入值A
比如說A=1,B=0,S=0的時候輸出是多少?S=0就是說:選擇A的值輸出,也就是說輸出值Z=A=1
就這麼簡單

同樣地,我們也可以有4選1選擇器

只不過控制輸入S變成了兩位(00,01,10,11,分別對應一二三四),道理還是一樣的

如果你對這個東東怎麼做成的感興趣的話。。。下面就是4選1選擇器的其中一種電路 = =



哦,還有。。本文使用的邏輯閘符號均是ANSI/IEEE Std 91-1984中的Distinctive shape,不是用方框符號。。。= =

你只要知道資料選擇器是幹啥的就好,不用惦記上邊那電路。。

------------------------------------------------------------------------------------------------------------

1. 計算機架構(Computer Architecture)

CPU、內部儲存器(Internal Storage Device)和輸入/輸出裝置(Input/Output Device, I/O)是電子計算機三大核心部件。內部儲存器可以是硬碟,記憶體,快取等;輸入裝置可以是滑鼠,鍵盤;輸出裝置可以有螢幕,音箱等等。。



當你開啟電腦硬碟上安裝的某個程式時,你的作業系統會把硬碟上的相應內容放入記憶體中。至於怎麼放,在記憶體的什麼地方放那可是一門大學問,光這個就夠一般人喝一壺的。。相關知識可以在大學的作業系統課程裡學到

比如說你放個音樂。要放音樂,先用滑鼠點開一個mp3檔案,於是你就使用了一個輸入裝置。這個輸入裝置會把一箇中斷請求(Interrupt Request)送到CPU那邊,結合來自作業系統的資訊後CPU就知道:哦,你用滑鼠點開那個mp3檔案了!於是:
1. CPU執行作業系統裡關於檔案關聯的程式碼,於是你的電腦就知道要用WMP開啟檔案了
2. 你的作業系統開始把WMP這個程式裡含有的指令和mp3檔案的內容從硬碟上拉進記憶體裡(還是CPU的工作)
3. 然後你的CPU開始一條一條地(雙核的話那你就當成兩條兩條地好了)執行記憶體裡的WMP程式指令(也就是如何解碼mp3),並且把解碼後的PCM位元流傳到音效卡上,再由音效卡把數字訊號轉換成模擬訊號送到音箱/耳機(輸出裝置)裡。So now you have music!

又比如說你要編輯一個txt檔案。還是先得用滑鼠點開檔案,又用了一次輸入裝置。於是:
1. CPU執行作業系統裡關於檔案關聯的程式碼,於是你的電腦就知道要用notepad開啟檔案了
2. 你的作業系統把notepad的程式指令和檔案內容拉進記憶體
3. 然後你的CPU又開始執行Notepad程式的指令了
4. 每當你敲一次鍵盤(還是輸入裝置!!),都會向CPU傳送一箇中斷請求好讓CPU知道你敲了某個鍵。比如說你敲個Y,那麼CPU就會把Y這個字元寫進記憶體裡。然後你要儲存的時候作業系統就會把記憶體裡改過的東東倒進硬盤裡!~

。。。好吧我承認實際過程跟這兒說的不大一樣並且複雜得多,有些細節會在後面詳細講,but that's the basic idea.

這大約就是CPU,輸入/輸出裝置和記憶體之間的互動方式了。

---------------------------------------------------------------------------------------------------

2.記憶體(Memory)

記憶體就是暫時儲存程式以及資料的地方,比如當我們在使用WPS處理文稿時,當你在鍵盤上敲入字元時,它就被存入記憶體中,當你選擇存檔時,記憶體中的資料才會被存入硬碟。一斷電記憶體上的東東就沒了

記憶體裡的資料是根據記憶體地址(Memory Address)來組織的。每個地址都是獨特的,每個地址一般來說對應著一個位元組(byte)=8 bit,我們管這叫Byte addressable memory.

在32 bit的系統上,記憶體地址的長度就是32 bit。那麼一個32 bit長度的二進位制數最大可以表示的數是多少呢?很簡單,2^32 = 4294967296。也就是說,32 bit的記憶體地址最大可以對應4294967296位元組的記憶體!

這個數字換算一下就可以得出它相當於4GB。現在你知道為什麼32位系統不支援4GB以上的記憶體了嗎?

------------------------------------------------------------------------------------------------------

3. 指令編碼(Instruction Encoding)

終於要說點正經的了。。前面說過CPU會執行記憶體/快取中的程式指令,可是這些指令是以什麼樣的形式儲存在記憶體裡的呢?要知道所謂的指令其實就是一長串的0和1而已。那CPU如何從這些0和1裡知道指令是什麼呢?這就是指令編碼的內容了。

先說說CPU。您說,CPU能幹啥?其實很簡單,無非就是加減乘除,讀寫記憶體,邏輯運算什麼的。若是複雜些的CPU可能指令集要大些,不過基本的指令大概就這些。CPU內部也有自己的儲存單元,叫做暫存器(Register),也是暫時用來放資料的地方,速度特別快,容量特別小。
就拿我經常用的NIOS II來說,它內部有32個暫存器,它可以執行的指令包括(不好意思我要用匯編語言了=_=):

add rA,rB,rC #把暫存器rB,rC裡的數加起來,結果放入暫存器rC
addi rB, rA, IMM16 #把rA裡的數跟一個16位的數相加,結果放入rB
beq rB,rA,LABEL #若rA=rB,則跳到LABEL指定的記憶體地址開始執行指令,否則繼續按照記憶體地址順序執行指令
stwio rB, b_o(rA) #從記憶體地址rA+b_o處讀取一個位元組,資料放入rB
ldwio rB, b_o(rA) #從記憶體地址rA+b_o處開始寫入一個位元組,寫入的資料在rB裡


等等

總結起來,CPU可以有以下幾個功能:
1.進行暫存器之間的運算和比較
2.由暫存器內指定的地址讀寫記憶體
3.分支指令,類似於C語言裡的if語句。比如跳到某個暫存器裡指定的記憶體地址開始讀取並執行指令

當然,更復雜的指令集是有可能的,不過這裡就不說了

---------------------------------------------------------------------------------------------

我知道讀者可能好幾樓沒見著個圖有點煩躁了,不過請有些耐心,等開始拼裝CPU的時候圖片絕對多。。。

Anyway,繼續說指令編碼
大致來說,上面的指令可以分為三大類:I-type,R-type,J-type
P.S.這種分類適用於MIPS架構的處理器,其他我就不知道了

1. I-type
以32 bit為例。一條I-type指令包括四個元素:
兩個暫存器編號,一個16位數字和一個操作碼

31-27位代表指令裡暫存器rA的編號
26-22位代表暫存器rB的編號
21-6位是一個16位的二進位制數
5-0位是操作碼

例子:
NIOS II彙編指令 addi r6,r7,310表示把暫存器r7裡的數加上310,結果放入暫存器r6。如果我們規定addi運算對應的六位操作碼是000011,那麼請問整條指令的編碼是?
解答:
暫存器r6的編號是6,即00110
暫存器r7的編號是7,即00111
數字310對應的二進位制數是0000000100110110
addi的操作碼是000011
所以整條指令的編碼就是00110 00111 0000000100110110 000011
-----------------------r6-----r7--------310---------addi------
共32位!
這就是I-type指令在記憶體裡存在的形式!!~

----------------------------------------------------------------------------

2. R-type

還是以32 bit為例。一條R-type指令通常包括四個元素:
三個暫存器編號,一個操作碼

31-27位是暫存器rA的編號
26-22位是暫存器rB的編號
21-17位是暫存器rC(一般來說這個是目標暫存器)的編號
16-6位是OPX,是操作碼
5-0位。。你當它沒用吧,寫上000000就好 = =

例子:
彙編指令 add r10,r9,r8是典型的R-type指令。它表示把暫存器r9,r8裡的數加起來,然後把結果寫入暫存器r10(目標暫存器)。若規定add運算的操作碼為00000011111,請問整條指令的編碼是?
解答:
暫存器r10的編號是10,即01010
暫存器r9的編號是9,即01001
暫存器r8的編號是8,即01000
add運算操作碼是00000011111
OP = 000000
所以整條指令的二進位制編碼是01001 01000 01010 00000011111 000000
---------------------------r9-----r8---r10------add-------OP
共32位!

-----------------------------------------------------------------------------------------

3. J-Type

一條32bit的J-Type指令包含兩個元素:
一個26位的數字(通常是記憶體地址)和一個6位的操作碼

31-6位是數字
5-0位是操作碼

例子:
彙編指令 call ROUTINE_3是典型的J-Type指令,它表示該指令執行完畢後CPU將從ROUTINE_3開始的記憶體地址讀取並執行其他指令。若ROUTINE_3開頭指令的記憶體地址是0x00002b3c,call的操作碼是000000,請問整條指令的二進位制編碼是?
解答:
16進位制數0x00002b3c = 0000 0000 0000 0000 0010 1011 0011 1101
call操作碼是000000
所以整個指令的編碼是00000000000000000010101100111101 000000
------------------------------ROUTINE_3--------------call--
還是32位!