轉載請遵循GNU開源宣言。Copyleft ! <2013>, <http://www.cnblogs.com/sciencefans from buaa 華羅庚班>
閱讀此文,你需要擁有以下基礎:
1.能理解本系列第2節和第4節;2.已經閱讀了第4節。
=========================================================================
(為什么mac總是配圖失敗呢,,)
很久沒有更新本系列了誒。。。有一個月了吧。但是經過這接近一個月來對code的重新閱讀以及對其他一些書的草草翻翻,更加進一步的對計算機領域本身,計算機的數學發展以及計算機的哲學發展這三個方面進行了了解和深入理解與思考。作為一個數學系的計算機系學生,加上這些理解,自然會有自己一些會對或錯的想法。或許這些將會在以后的文章中隱隱約約地顯現出來。
一直在糾結到底應該先寫匯編還是先寫自動操作。csapp一書是直接從寄存器開始講匯編,剛開始開的時候還真有些不好理解,有些東西沒有聽說過(畢竟是數學系的),而計算機組成與設計(以后簡稱COD H/S)一書卻索性放到了附錄,唯獨code一書是從最簡單慢慢在不知不覺中讓讀者發現:哇,我現在看的原來就是匯編啊!那么我決定走code路線~
那么進入正題吧~
之前我們已經做出了最簡易的加減器,單位存儲器。其中加減器可以認為是一個非常不完善的cpu,而存儲器可以認為是最簡陋的RAM。面對上一次提出的三個問題,今天開始的接下來三節一共要搞明白以下幾件事:
- 多位存儲器;
- 怎樣自動就能不停地進行累加;
- ‘累加’該怎么停止;
- 怎么讓‘硬件’通過‘代碼’自動化。
首先是多位存儲器。上一次已經做出了一個單位存儲器,在本文中我用下面這個集成小塊兒來代表它(具體電路見第四節):

根據之前我們制作多位運算器的經驗,多位存儲器應該也是多個單位存儲器的某種形式的鏈接,唯獨不同的一點就是需要增加一些調度電路——它必須知道總線發過來的信號應該給多位存儲器中的哪一‘位’,它也應該知道怎么進行‘讀’‘寫’操作。
首先要解決的問題是‘調度’電路怎么設計。現在以8位存儲器為例,想要確定某一時刻數據應該往8個子位的哪一位存,應該消耗多少輸入端口來確定呢?或者說,假設這八個單位存儲器的地址分別是1,2,3,。。。,8,需要多少個輸入端口來把他們區分開呢?這里要引入一個新的東西——3-8譯碼器。我們知道,想要表達8種不同的狀態最少需要3個二進制位(還記得小白鼠的實驗那個游戲嗎?8杯水只有一杯有毒,只喂一次的情況下最小需要3只小白鼠才能知道哪杯有水)。所以輸入地址位應該是3個。下面就是3-8譯碼器(顧名思義)的電路:

左下角的DI代表的意思是數據輸入,這個輸入的數據應該給右邊8個端口中的哪一個呢?由左下角的S0,S1,S2確定。仔細看看電路就不難發現這個電路的精妙所在。S0,S1,S2三個端口的原本信號和取反信號分別構成了1,0,三個1,0位的全部結合構成了這8個輸出口的‘地址’——000,001,010,。。。,111.
解決了數據輸入調度,現在該解決數據輸出調度了,輸出和輸入是兩個相反的過程,所以輸出調度就是把輸入調度元件反着畫一下就好了,他有一個新名字——8-1選擇器:

左邊的輸入口自上向下分別是8個單位存儲器的輸出,三個S地址調度器代表特定的某個輸出口被打開。右邊的輸出端口就代表被選中的那一‘位’存儲器的輸出值。
現在准備工作都完成了,分別把3-8譯碼器,8個單位鎖存器,8-1選擇器進行連接,變成下面這個樣子:

藍色,紅色和綠色本別是3-8譯碼器,單位鎖存器和8-1選擇器。
大功告成之后,該做測試了:現在這個8位存儲器初期的狀態是:EEEE EEEE(未知狀態)
現在我想寫入0001 0111怎么辦呢?只需要兩步:1.全部復位成0:0000 0000
2.將0,1,2,4位寫入1
具體來說,只需要先將D(data)位一直輸入0,打開W位(輸入1),再依次在A(address)0,A1,A2位輸入000,001一直到111即可完成歸零操作,再將D輸入1,打開W,地址依次輸入000,001,010,100即可完成寫入工作。最后的狀態如下圖:

畫紅圈代表該位存儲值為1,不畫代表為0.各位存儲器的編號已經標出,很容易讀出:0001 0111 和我們的預期相同。
我們知道,8bit=1byte,也就是說一個8位存儲器的存儲能力是1byte。我們可以並聯很多個這樣的8位存儲器,比如如果把1073741824個這樣的8位存儲器並連到一塊兒,就變成了一個容量為1GByte的大存儲器,而那時候我們的地址位就不僅僅是3個就能存下這么簡單的了。思考一個問題:現在主流的32/64位操作系統分別最大支持4G和16EB,(1EB=1024PB=1048576TB=......)(實際也到不了那么大,這和總線尋址,操作系統有關),這是為什么呢?再想想剛才3-8譯碼器的原理,不難得出以下公式:
1 BitNum = Log(2)(MaxMemBit)
也就是說地址位數(比如3-8譯碼器的地址位為3,32位操作系統地址最大是32位)等於最大內存尋址大小對2取對數。
事實上,這里所說的‘地址’只是一個我們想當然的某一個‘位’的地址,事實並非如此。人們把存儲器分為很多區,每個區分為很多存儲器板,每個存儲器板會有一定量的存儲體,每一個存儲體可以存儲很多位,每一個位在存儲體里有特定的地址。這就相當於我們把100000個學生不僅僅從學號進行尋找,還給他們分配了班級,系別,年級等等嵌套式的整理,這使得管理起來非常明了,但是本質上和我們對他們直接進行‘學號尋址’是一樣的。這些內容將在以后的總線設計中提到。
綜上,我們對內存和地址的關系或許有了一定的了解,這樣一來我們就有了一些大膽的猜想——既然所有計算機操作在處理器上都可以歸結成‘加法’,‘移位’等非常少的基本邏輯運算,那么實現自動‘累加’就是實現自動化的一大進步。累加的加數的存儲問題已經在本節被解決了,而怎么讓處理器來處理‘累加’呢?每次‘累加’的結果怎么存儲才有效率?這些將在不久以后解決。
至此,一個多位存儲器也基本完成了。
