從電腦出現(xiàn)至今就一直被死機伴隨著,幾乎沒有誰的電腦從不遭遇死機,
內(nèi)存與死機的關(guān)系
。在使用過程中,偶爾一次死機應該算是正,F(xiàn)象,如果經(jīng)常死機,電腦就存在一定的問題了。那么,電腦為什么會死機呢?有哪些因素會造成電腦死機呢?要搞清楚這些問題,首先要弄清楚,到底什么是死機?為什么會發(fā)生死機?造成死機的原因是多種多樣的,有軟件問題,有硬件問題,不過,死機的本質(zhì)都是一樣的。
早在N年前,我主持某大學計算機專業(yè)本科生畢業(yè)答辯的時候,就向某學生提出過這樣兩個問題:
1.電腦死機的時候,CPU在干什么(或者說,CPU處于什么狀態(tài)?)”
2.在計算機中,無論指令代碼還是數(shù)據(jù)代碼,都是用二進制來表示的,請問,CPU是如何判定某二進制代碼是指令代碼還是數(shù)據(jù)代碼? //本文引用自www.45it.com電腦軟硬件應用網(wǎng)
其實,上面兩個問題的實質(zhì)是一樣的,主要涉及到CPU是如何取得指令和如何執(zhí)行指令的,把這兩個問題搞清楚了,死機的問題也就容易理解了。
首先來看看,馮.諾依曼結(jié)構(gòu)的電腦是如何取得指令、又是如何執(zhí)行指令的:
馮.諾依曼(1903~1957),匈牙利裔數(shù)學家,1945年戈德斯坦、勃克斯等人,聯(lián)名發(fā)表了一篇長達101頁紙的報告,即計算機史上著名的“101頁報告”,提出了現(xiàn)代計算機結(jié)構(gòu)的理論模型--存儲程序計算機模型(Stored Program Computer),這就是今天計算機最基本的原理模型。
這種結(jié)構(gòu)類型計算機工作的時候,首先必須把完成工作步驟和相關(guān)的數(shù)據(jù)用二進制代碼表示出來(編寫程序),然后再把它們保存在計算機的內(nèi)存中,CPU依次從內(nèi)存中讀相關(guān)的指令代碼和數(shù)據(jù)進行運算,直到完成整個運算過程并輸出結(jié)果。
要完成這樣的運算過程,人們在設(shè)計運算器(CPU)的時候,首先就要考慮的是,在一段內(nèi)存中,CPU怎樣區(qū)分指令代碼和數(shù)據(jù)代碼。熟悉計算機的人都清楚,指令用來確定“做什么”和“怎樣做”,數(shù)據(jù)是“做”的時候需要原始數(shù)。
比如:要計算機做1+2=?中,“+”表示要做什么和怎樣做,1和2則是做的時候需要的原始數(shù),F(xiàn)在假設(shè)某CPU中,“+”用二進制“00000001”來表示,“1、2”分別用“00000001、00000010”來表示。那么,這段程序存入內(nèi)存中就是這樣的:
XXXX1:00000001
XXXX2:00000001
XXXX3:00000010 前面的XXXX1 XXXX2 XXXX3表示內(nèi)存的地址
從上面可以看出,“+”指令和被加數(shù)是完全相同的,當然,這是我故意這樣假設(shè)的,但是,在實際情況中,這種情況是大量存在的。在正常情況下,CPU只能把XXXX1內(nèi)存中的00000001作為指令,XXXX2內(nèi)存中的00000001作為被加數(shù)才能得到正確的結(jié)果。那么CPU如何才能做到不把第二個00000001也當成“+”呢?
1.人們把內(nèi)存的某個地址規(guī)定為起始地址(又稱為復位地址),也就是說,當計算機開機或者被強行復位(也就是機箱上那個重啟動按鈕按下的的時候),CPU立即跳轉(zhuǎn)到這個地址中,并且把它里面的代碼作為指令來執(zhí)行,同時根據(jù)這個指令的長度和格式判斷下一條指令在什么地方。
對于X86系列CPU(也就是現(xiàn)在人們常用的什么奔XX、賽XX系列),它的復位地址是FFFF0,如果表示成邏輯地址則是:FFFF:0000。對DEBUG比較熟悉的朋友或者會在一些高級語言中嵌入?yún)R編語言的朋友可以這樣做一個試驗:
用DEBUG執(zhí)行一條指令(這是一條無條件跳轉(zhuǎn)指令):jmp FFFF:0000,或者在高級語言中嵌入這條匯編指令,執(zhí)行后,你就會發(fā)現(xiàn),計算機重新啟動了,
電腦資料
《內(nèi)存與死機的關(guān)系》(http://www.szmdbiao.com)。其實,用程序控制計算機重啟的最本質(zhì)的操作就是這樣的。2.給各種指令規(guī)定了相應的長度和格式。比如:某數(shù)+某數(shù)這條指令就規(guī)定:這條指令的長度是3個字節(jié),其中第一個字節(jié)表示“+”,后面兩個字節(jié)表示被加數(shù)和加數(shù)。于是,當CPU到達這個指令后,就自動把第一個代碼作為指令,后面兩個代碼作為數(shù)據(jù),依次類推,第4個代碼就必然是指令…..
現(xiàn)在假設(shè),CPU在執(zhí)行指令的時候因某種原因,誤把本來是數(shù)據(jù)的代碼當成了指令,結(jié)果除了是計算結(jié)果出錯外死機也就是必然的了。
還是以前面那個加法程序為例:當CPU把第三個代碼(也就是00000010)當成了指令,而恰好這個代碼是一跳轉(zhuǎn)指令,CPU的執(zhí)行結(jié)果將是:XXXX3--跳轉(zhuǎn)--執(zhí)行--跳轉(zhuǎn)--執(zhí)行……..進入周而復始的亂條,不過注意,雖然是在亂跳,CPU卻始終是在不停的正常地執(zhí)行指令,所謂的“亂”是對用戶而言,對CPU來說卻是正常的。
還有一種情況就是,如果恰好跳轉(zhuǎn)到了FFFF:0000這個地址,計算機便重新啟動了。呵呵,,這下搞清楚了為什么計算機有時會“莫名其妙地重啟”了把。
有朋友可能會問,內(nèi)存中怎么可能有如此多的跳轉(zhuǎn)指令呢?是怎么形成的呢?
計算機中的最小存儲單位是字節(jié)(8個二進制位),指令功能、長度和格式也是在一個字節(jié)中規(guī)定的。因此,平均來說,每256個代碼中就有可能出現(xiàn)一條跳轉(zhuǎn)指令(8位二進制數(shù)最多表示256)。
還有一種情況:現(xiàn)在計算機的內(nèi)存已經(jīng)達到數(shù)G的存儲容量,絕大多數(shù)都不可能用到這個極限,也就是說,有相當長一段區(qū)域是空白,即使內(nèi)存只有數(shù)百M的計算機中也不可能把內(nèi)存用完,同樣存在相當數(shù)量的空白區(qū)域。特別需要注意的是,空白區(qū)域不等于里面就沒有代碼。因為,在數(shù)字邏輯電路中,不可能存在“沒有”這種情況,即使是表示沒有(叫做“空”--NULL)也是要用一個代碼來表示的(NULL用00000000)來表示,所以,空白區(qū)域內(nèi)的代碼是“11111111”或者干脆就是一些隨機代碼。X86系列的CPU“11111111”是一條單字節(jié)的指令nop--空操作指令,當CPU跳轉(zhuǎn)到這些空白區(qū)域時,雖然不會發(fā)生再次跳轉(zhuǎn)的現(xiàn)象,CPU也會逐條執(zhí)行這些代碼,執(zhí)行到最后一個內(nèi)存后,CPU將會回到內(nèi)存的0號起始地方然后又從頭開始執(zhí)行程序。
有朋友問了,如果硬盤出錯會不會死機呢?這個問題要這樣看。CPU從硬盤中調(diào)入數(shù)據(jù)的時候會對硬盤數(shù)據(jù)做比較嚴格的校驗(一般是CRC--循環(huán)冗余校驗),如果校驗成功,則不會死機,如果校驗失敗,CPU會給予用戶提示“校驗失敗或者文件損壞”--當然也不會死機;只有在硬盤上的文件已經(jīng)損壞,硬盤把數(shù)據(jù)傳給CPU的時候“自己沒有發(fā)現(xiàn)”造成的數(shù)據(jù)混亂。所以,硬盤數(shù)據(jù)損壞后,只能造成數(shù)據(jù)丟失,無法執(zhí)行程序,也可能無法啟動計算機。不過,有一種情況例外,那就是硬盤上的某區(qū)域做成的虛擬內(nèi)存,如果這個區(qū)域損壞是有可能死機。
內(nèi)存的啟動監(jiān)測問題,計算機在開機的時候會對內(nèi)存進行檢測,這種檢測的方法不外乎有如下一些:
1.最簡單的檢測方法:把內(nèi)存從頭到尾讀一遍,能夠讀出數(shù)據(jù)便認為內(nèi)存正確。
2.稍微復雜一些的檢測方法:把內(nèi)存從頭到尾讀、寫一遍,能夠讀寫數(shù)據(jù)便認為內(nèi)存正確。
3.再復雜一些的檢測方法:把內(nèi)存從頭到尾讀、寫數(shù)遍能夠讀寫數(shù)據(jù)便認為內(nèi)存正確。
4.簡單的校驗檢測方法:把內(nèi)存從頭到尾讀、寫數(shù)遍,讀出的數(shù)據(jù)和寫入的數(shù)據(jù)進行比較,能夠讀寫、并且讀的數(shù)據(jù)和寫的數(shù)據(jù)相同,則認為內(nèi)存正確
5.比較復雜的校驗檢測方法:對內(nèi)存讀寫的數(shù)據(jù)同時進行奇偶校驗和CRC校驗,這種方法多用于高檔服務(wù)器,同時,能夠做奇偶校驗的內(nèi)存(ECC內(nèi)存)價格比普通內(nèi)存貴10倍以上(不知道為什么)。