分段式內(nèi)存管理
我們知道,程序的內(nèi)存從內(nèi)容上可以分為存放機器指令的代碼區(qū)域、存放全局變量的數(shù)據(jù)區(qū)域、保存函數(shù)運行時信息的棧區(qū)等,顯然我們可以將程序按照這種劃分進行分段管理,段內(nèi)使用相對地址,這樣無論這些段被加載到內(nèi)存的哪個區(qū)域我們都能方便的計算出正確的物理內(nèi)存地址。
我們將各個段在內(nèi)存中的起始地址放到專用的寄存器中,X86 CPU中有這樣幾個段寄存器,CS、DS、SS以及ES,這些寄存器有什么用呢?這幾個寄存器就用來存放各個段在內(nèi)存中的起始地址(暫且這樣理解,稍后你會發(fā)現(xiàn)這些寄存器的真實用法):
- 保存機器指令的區(qū)域,這個區(qū)域就是我們所說的代碼段(Code Segment),因此我們可以使用一個寄存器來專門指向代碼段,這就是CS寄存器的作用,CS也是Code Segment的縮寫。
- 同樣的道理,程序運行起來后還有專門的區(qū)域用來保存數(shù)據(jù),因此必須要專門的寄存器指向數(shù)據(jù)段(Data Segment),這就是DS寄存器的作用,DS是Data Segment的縮寫。
- 程序運行起來后還有運行時棧(Stack Segment),因此可以使用SS寄存器來指向程序員運行時棧,SS是Stack Segment的縮寫。
- 此外還有ES寄存器,Extra Segment,其用作臨時段寄存器。
除了內(nèi)存分段管理之外, 我們的程序可以讀寫任意內(nèi)存區(qū)域 ,有的同學可能不以為意,這又能怎樣呢?
沒有內(nèi)存保護會怎樣?
至今,在多線程編程中這個問題依然困擾著程序員,因為同一個進程中的線程共享同一個地址空間,這也就意味著你的線程可以修改地址空間中任何可寫的區(qū)域,包括棧區(qū)以及堆區(qū),當然這也就意味著其它線程可以修改你的線程使用的數(shù)據(jù),這是多線程中一大類bug的來源,關(guān)于這一部分的內(nèi)容你可以參考《線程間到底共享了哪些進程資源?》。
而這個問題在內(nèi)存地址沒有任何保護情況下更加嚴重,因為這時不是一個進程而是多有進程包括操作系統(tǒng)都共享同一個物理內(nèi)存地址,任何一個進程都可以修改內(nèi)存中任何位置,你的進程可以破壞其他進程使用的內(nèi)存,可以破壞操作系統(tǒng)使用的內(nèi)存,破壞其它進程大不了重新啟動這個進程,但是如果破壞了操作系統(tǒng)那么沒有辦法,此時你只能重新啟動計算機,如果CPU沒有提供內(nèi)存保護機制,那么操作系統(tǒng)連自己都保護不了更何況去保護其它進程。
沒想到吧,看似簡單直接的內(nèi)存讀寫竟然會有這么多問題。
實模式
好啦,到目前為止讓我們暫且總結(jié)一下。
- 絕對的內(nèi)存地址不好用,這樣的地址必須將程序加載到內(nèi)存的特定位置上,為解決這個問題使用相對地址,x86中為每個程序的區(qū)域都配備有專用的寄存器用來存放該段在內(nèi)存中的起始地址,這樣就可以根據(jù)基址加偏移計算出物理內(nèi)存地址,注意,這里計算出來的是真實的物理內(nèi)存地址。
- 內(nèi)存讀寫沒有任何保護,程序可以讀寫內(nèi)存的任何區(qū)域。
實際上這就是早前內(nèi)存管理的模式,非常直接非常原始,x86 CPU將這種原始的內(nèi)存管理方法稱之為實模式,real mode,這種模式也被稱之為 real address mode ,顧名思義,我們在程序中看到的都是真實的物理內(nèi)存地址。
原來,早期的x86 CPU能訪問的最大內(nèi)存被限制在1MB(2^20 byte),你可能會想這可用內(nèi)存也太少了吧,對于當今程序員或者用戶來說1MB幾乎什么都干不了,哪怕都存不下一首歌,然而在上世紀80年代,1MB內(nèi)存是一片極為廣闊的空間,以至于比爾蓋茨在上世紀80年代說過:640k ought to be enough for anyone,對大部分人來說640K內(nèi)存已經(jīng)足夠用了。
除此之外,更加捉襟見肘的是早期x86 CPU寄存器只有16位,16位寄存器是沒有辦法訪問整個1MB內(nèi)存的,16位寄存器最多能訪問64K大小的內(nèi)存,要想訪問1MB內(nèi)存那么內(nèi)存地址就需要20位,而寄存器本身就16位,因此根本裝不下,怎么辦呢?
很簡單,一個寄存器不夠我們就用兩個,第一個寄存器被叫做selector,說白了其實存放的是儲物柜區(qū)域的編號,因此也叫做段寄存器, segment register,管叫做區(qū)域還是叫做段本質(zhì)上沒啥區(qū)別。
第二個寄存器被叫做offset,說白了就是區(qū)域內(nèi)的編號或者叫做區(qū)域內(nèi)的偏移,這樣真正的內(nèi)存地址就由兩部分組成 selector:offset ,此時內(nèi)存地址的計算方式是這樣的:
16 ? selector + offset
此時給定一個段寄存器再給出一個偏移我們就能直接在內(nèi)存中找到需要的數(shù)據(jù):
因此這里計算出來的內(nèi)存地址就是物理內(nèi)存地址。
此外,在實模式下CPU不提供內(nèi)存保護機制,程序可以隨意讀寫任何內(nèi)存區(qū)域,哪怕是操作系統(tǒng)所在的區(qū)域其它程序也可以讀寫。
現(xiàn)在可以總結(jié)下早期x86處理器的特點了:
- 尋址空間有限,只有1MB
- 利用 selector:offset的方式利用兩個16位寄存器來尋址1MB內(nèi)存
- 沒有內(nèi)存保護機制,當然,沒有內(nèi)存保護機制的一大優(yōu)點就在于內(nèi)存讀寫速度要更快,原因就在于不需要經(jīng)過虛擬內(nèi)存地址到物理內(nèi)存地址的轉(zhuǎn)換,也不需要進行任何檢查(這可能是實模式下僅有的優(yōu)點)
在80286之前,所有x86 CPU都運行在實模式下,而為了后向兼容,即使是現(xiàn)代x86在重置(加電時)后也會首先進入實模式,后續(xù)才會跳轉(zhuǎn)到保護模式(protected mode),關(guān)于保護模式我們在后續(xù)文章中講解。
實模式與操作系統(tǒng)
實模式是x86系列處理器最早期的內(nèi)存管理模式,這一時期的操作系統(tǒng)別無選擇,只能運行在這種模式下,早期的DOS系統(tǒng)以及早期的Microsoft Windows操作系統(tǒng)就運行在實模式下。
雖然實模式理解起來很簡單,但這種模式最主要的問題在于:
- 把物理內(nèi)存暴露給程序
- 沒有內(nèi)存保護機制
這兩者結(jié)合起來的后果就是 程序不被受限 ,程序員都知道,我們寫的代碼充滿了bug,在現(xiàn)代操作系統(tǒng)中程序很容易把自己搞掛,而在早期的操作系統(tǒng)中程序就會很容易的把整個系統(tǒng)搞掛,為解決這一問題,x86 CPU在80286開始引入保護模式,后續(xù)文章會有詳細講解。
盡管現(xiàn)代操作系統(tǒng)(Windows、Linux)等早已不運行在實模式下,然而實模式卻依然保留了下來,你可能會想為什么x86 CPU依然需要保留實模式呢?
我們都知道代碼有屎山一說,其實對于歷史悠久的x86來說也有類似的問題。
CPU這種硬件和軟件一樣也是在不斷演變進化的,從16位實模式演進到了32位保護模式以及現(xiàn)代的64位處理器,但早期程序員圍繞著16位實模式的x86CPU編寫了很多軟件,當CPU發(fā)展到32位保護模式時之前的基于16位實模式編寫的軟件該怎么辦?不支持了嗎?不支持的話只有兩種可能:1) 用戶不再購買不兼容16位軟件的CPU 2) 重寫代碼,以程序員的尿性來說大概率不會重寫,intel也非常識時務(wù),因此在后來的32位乃至現(xiàn)代的64位處理器上依然保留了實模式,x86系列處理器在重置時會首先進入實模式,對于不使用實模式的現(xiàn)代操作系統(tǒng)來說簡單的初始化工作后會跳轉(zhuǎn)到保護模式。
因此我們可以看到,實模式就像原始的進化基因一樣依然存在,就像動物胚胎有腮一樣,只不過該過程一閃而過,實模式也是在計算機啟動階段快速閃現(xiàn),這種古老的內(nèi)存管理方式依然留下了自己的烙印。
總結(jié)
實模式是一種非常古老的內(nèi)存管理方式,在這種方法下程序員直面物理內(nèi)存,且處理器沒有提供內(nèi)存讀寫機制,程序員可讀寫任何內(nèi)存區(qū)域。
實際上實模式對于現(xiàn)代操作系統(tǒng)來幾乎沒什么用處,只不過如果你針對x86 CPU編寫操作系統(tǒng)那么實模式是必須要了解的,但對于其它CPU來說則沒有這樣的歷史包袱,因此有很多操作系統(tǒng)教材開始基于非X86平臺來講解,這樣能更快速的講解操作系統(tǒng)而不是在一上來就在各種內(nèi)存模式中打轉(zhuǎn)。
注意,本文提到的實模式僅僅針對x86系列處理器而言,對于上層應(yīng)用的大部分程序員來說根本就不需要關(guān)心實模式,然而技術(shù)就和生物一樣也在不斷演變進化,了解過去才能更好的理解當下以及未來。
-
cpu
+關(guān)注
關(guān)注
68文章
11066瀏覽量
216617 -
內(nèi)存
+關(guān)注
關(guān)注
8文章
3117瀏覽量
75153 -
操作系統(tǒng)
+關(guān)注
關(guān)注
37文章
7130瀏覽量
125345
發(fā)布評論請先 登錄
什么是操作系統(tǒng)
適合AMP同構(gòu)非對稱模式下的操作系統(tǒng)
【安富萊】【RTX操作系統(tǒng)教程】第21章 RTX低功耗之睡眠模式
ARM CPU操作系統(tǒng)
HarmonyOS鴻蒙操作系統(tǒng)之什么是“基于微內(nèi)核的全場景分布式操作系統(tǒng)”?
如何選擇ARM CPU的操作系統(tǒng)?
MOS微型操作系統(tǒng)的設(shè)計與實現(xiàn)
什么是VxWorks操作系統(tǒng)
32位cpu、程序、操作系統(tǒng)是什么意思
Linux操作系統(tǒng)實訓項目_虛擬機設(shè)置基礎(chǔ)_RHEL_5.0_2
windows10操作系統(tǒng)安全模式的使用技巧
CPU的工作模式

如何使服務(wù)器CPU在超頻模式下運行
國產(chǎn)CPU和操作系統(tǒng)被納入政府采購清單:加速換國產(chǎn)OS

評論