分段
基本概念
在編寫代碼的時候袭祟,程序員認為它是由主程序加上一組方法验残,過程或者函數(shù)的集合。他還包括這種數(shù)據(jù)結(jié)構(gòu):對象巾乳,數(shù)組您没,堆棧,變量胆绊。每個模塊或者數(shù)據(jù)元素通過名字來引用氨鹏。而不關(guān)心具體的內(nèi)存位置。
分段就是支持這種用戶視圖的內(nèi)存管理方法压状。邏輯地址空間是由一組段構(gòu)成仆抵。每個段都有名稱和長度,比如种冬,代碼段镣丑,數(shù)據(jù)段,堆棧娱两,堆等等莺匠。
地址指定了段名稱和段內(nèi)偏移。所以段一般是由兩個量來進行表示:
<段號十兢, 偏移>
通常趣竣,在編譯用戶程序的時候,編譯器會自動生成:
- 代碼
- 全局變量
- 堆
- 棧
- 程序庫
分段的硬件實現(xiàn)
雖然用戶可以實現(xiàn)通過二維地址來引用程序內(nèi)的對象旱物,但是實際物理內(nèi)存還是一維的字節(jié)數(shù)組遥缕。因此需要我們需要定義一個映射方法,把二維地址轉(zhuǎn)換為一維地址宵呛。
這個地址是通過段表 來實現(xiàn)的通砍。段表的每個條目都有一個段基地址和段界限。段基地址包含該段在內(nèi)存中的開始物理地址,而界限地址指定該段的長度封孙。
從圖中迹冤,我們可以看到段表和每個段的分布情況。
再看看分段的硬件實現(xiàn)虎忌,每個邏輯地址都有兩個部分來實現(xiàn)泡徙,段號s和偏移d。 當我們從CPU的指令中得到一個地址時膜蠢,它有段號和偏移d堪藐,段號首先去段表中進行索引,獲取到段基(base)地址挑围,然后加上偏移d,然后和 界限地址進行比較礁竞,得到最終的物理內(nèi)存地址。(這里段表上兩個元素實際上是基地址寄存器和界限寄存器組成的結(jié)構(gòu)體數(shù)組)杉辙。
分頁
分段允許進程的物理地址空間可以分為多個段模捂,從而地址可以是非連續(xù)的。然而分段還是避免不了有外部碎片的情況蜘矢,因為在給每個段分配內(nèi)存的時候狂男,各個段的大小是不一樣的。從而讓整塊物理內(nèi)存還是會有縫隙品腹。分頁避免了這種情況岖食。
基本概念
實現(xiàn)分頁的最基本方法涉及到將物理內(nèi)存分為固定大小的塊,稱為幀或者頁幀(frame舞吭,從英文名可以看出來這是個框架)泡垃;而將邏輯內(nèi)存也分為同意大小的塊,叫做頁或者頁面(page, 從英文名可以看出來這是一頁紙)羡鸥。
當需要執(zhí)行一個進程時蔑穴,它的頁從文件系統(tǒng)或者磁盤中加載到內(nèi)存的可用頁幀中。磁盤也被劃分為固定大小的塊兄春,它與單個內(nèi)存幀(frame)或者分為多個內(nèi)存幀的大小一樣澎剥。
分頁的硬件支持
分頁的硬件支持和分段類似锡溯,由CPU解碼后的指令地址分為兩個部分:頁碼(page number)和頁偏移(page offset)赶舆。
頁碼作為頁的索引。頁表包含每頁所有物理內(nèi)存的基地址祭饭。這個基地址與頁偏移的組合形成了物理內(nèi)存地址芜茵。
再看看頁表的結(jié)構(gòu)(注意這里的地址用的是幀碼,也就是frame的頁號倡蝙,而不是字節(jié))九串。
我們通過上面的學(xué)習,應(yīng)該可以看到,分頁本身是一種動態(tài)的重定向猪钮。每個邏輯地址由分頁硬件綁定某一個物理地址品山。采用分頁類似于一個基地址寄存器,每個基址代表一個一個內(nèi)存幀烤低。
當系統(tǒng)進程需要執(zhí)行時肘交,它將檢驗該進程的大小,進程的每頁都需要一幀扑馁。因此一個進程需要n頁涯呻,那么內(nèi)存中至少應(yīng)該有n幀。如果有腻要,那么可分配給新進程复罐。進程的第一頁裝入一個已分配的幀,幀碼會在裝入后寫到進程的頁表中雄家,下一頁分配給另一幀效诅,然后幀碼也會寫到進程的頁表中。
有了分頁咳短,程序員就可以將內(nèi)存看做一整塊來處理填帽。內(nèi)存的分配和管理交給操作系統(tǒng)。他可以認為他的程序在邏輯上是連續(xù)的咙好,但是實際上篡腌,物理內(nèi)存中他們是分布在不同的幀上的。在操作系統(tǒng)管理內(nèi)存的分配時:它需要知道哪些幀已經(jīng)分配勾效,哪些幀空著嘹悼,總共有多少幀。這些都在內(nèi)核的叫做幀表 (frame table)的數(shù)據(jù)結(jié)構(gòu)中层宫。在幀表中每個條目對應(yīng)一個幀杨伙,以表示該幀是空閑還是已占用;如果占用萌腿,是被那個進程占用限匣。
分頁的效率討論
頁表具體的結(jié)構(gòu)是怎樣的?
每個操作系統(tǒng)都有自己保存頁表的方法毁菱。有的系統(tǒng)為每個進程分配一個頁表米死,然后通過指針保存在PCB中。當啟動一個進程的時候贮庞,他應(yīng)該首先加載一個用戶寄存器峦筒,并通過保存的用戶頁表來定義正確的硬件頁表值。頁表的硬件實現(xiàn)時怎樣的窗慎?
頁表的硬件實現(xiàn)有很多種物喷,但是最簡單的方法是通過一組專用的寄存器來實現(xiàn)卤材。這些寄存器應(yīng)用高速邏輯電路來構(gòu)成勤庐,以高效的進行分頁地址的轉(zhuǎn)換催束。由于每次訪問內(nèi)存都要經(jīng)過分頁映射痒谴,因此效率是一個重要的考慮因素榕订。CPU分派器在加載其他寄存器時隘竭,當然也需要加載這些寄存器可训,當然绘梦,這些頁表寄存器的加載指令也是特權(quán)的嘀掸。用寄存器來實現(xiàn)頁表的問題材蹬?
如果頁表比較小的時候实幕,用頁表寄存器時效率是很高的。但是現(xiàn)在的計算機基本都允許頁表很大堤器,對這些機器昆庇,采用寄存器就不行了。因此闸溃,頁表需要放在內(nèi)存中整吆,并將頁表基地址寄存器(PTBR)指向頁表,改變頁表只需要操作這一個寄存器就可以了辉川。采用頁表基地址寄存器的效率表蝙?
采用這種方法的問題是訪問用戶內(nèi)存位置的所需時間,如果需要訪問位置i乓旗, 那么應(yīng)該首先利用 PTBR的值府蛇,再加上i的頁碼,作為偏移屿愚,來查找頁表汇跨。這一任務(wù)需要內(nèi)存訪問。 根據(jù)所得的幀碼妆距,再加上頁偏移穷遂,就得到了真是的物理地址。接著就可以訪問內(nèi)存內(nèi)的所需位置娱据。采用這種方案蚪黑,訪問一個字節(jié)需要兩次內(nèi)存訪問(一次是頁表,一次是字節(jié))中剩。這樣內(nèi)存的訪問效率就減半了忌穿。
因為效率問題,我們的解決方案是采用專用的咽安,小的伴网,查找快速的高速硬件緩沖蓬推,它稱為轉(zhuǎn)換表緩沖區(qū)(TLB)妆棒。它是一個關(guān)鍵的高速內(nèi)存。
-TLB的工作原理
TLB條目由兩部分組成:鍵和值。當關(guān)聯(lián)內(nèi)存根據(jù)給定值查找時糕珊,它會同時與所有的鍵進行比較动分。那么就得到相應(yīng)的值。搜索的特別快『煅。現(xiàn)代TLB的查找硬件是指令流的一部分澜公,基本不會考慮性能代價。
TLB只包含了少量的頁表條目喇肋。當CPU產(chǎn)生一個邏輯地址后坟乾,它的頁碼就送到TLB,如果他能找到這個頁碼蝶防,它的幀碼也就立即可用甚侣,可用于訪問內(nèi)存。如果頁碼不在TLB中间学,那么就需要訪問頁表(訪問內(nèi)存)殷费。取決于CPU,這可能由硬件自動處理或者通過系統(tǒng)的中斷來處理低葫。當?shù)玫綆a后详羡,就可以用它來訪問內(nèi)存,同時還會把頁碼和頁幀加到TLB中嘿悬。
有的TLB在每個TLB條目中還保存地址空間標識符实柠,他唯一標識每個進程,并為進程提供地址空間的保護善涨。
TLB是一個硬件功能主到,我們不需要關(guān)心,但是了解他的功能和特性躯概,有利于我們在開發(fā)時登钥,進行系統(tǒng)的優(yōu)化。
分頁的安全討論
分頁環(huán)境下的內(nèi)存保護是通過與每個幀關(guān)聯(lián)的保護位來實現(xiàn)的娶靡,通常這些 保護位會保存在頁表中牧牢。
用一個位可以定義一個頁是可讀可寫或只可讀。每次內(nèi)存引用都要通過頁表姿锭,來查找正確的幀碼塔鳍。在計算物理地址的同時,還可以通過檢查保護位來保護系統(tǒng)對內(nèi)存的正確操作呻此。
還有一個位通常與頁表中的每一條項目相關(guān)聯(lián):有效-無效位轮纫。
當該位是有效位時,該值表示相關(guān)的頁在進程的邏輯空間中內(nèi)焚鲜,因此它是合法的頁掌唾。
當改為為無效位時放前,表示相關(guān)的頁不在進程的邏輯地址空間內(nèi)。
通過有效--無效位糯彬,非法地址會被捕捉凭语,然后操作對該地址進行允許和不允許對某頁的訪問。
對于上圖:14位地址空間 (016383)的系統(tǒng)撩扒,假設(shè)有一個程序似扔,它的有效地址空間是010468。如果頁的大小是2k,那么他會有5個頁表搓谆。然而炒辉,如果試圖產(chǎn)生頁表 6和頁表7,那么操作系統(tǒng)就會根據(jù)有效-無效位的捕捉到非法操作泉手。
共享頁
分頁的內(nèi)存機制辆脸,還有一個優(yōu)先就是可以共享公共代碼。
對于一個分時系統(tǒng)螃诅,假設(shè)有一個支持40個用戶的系統(tǒng)啡氢,每個用戶都指向一個文本編輯器,每個文本編輯器包括150k的代碼和50k的數(shù)據(jù)空間术裸,那么久需要8000kb的內(nèi)存來支持40個用戶倘是。
但是,如果代碼是可重入代碼袭艺。則可以進行共享搀崭。
可沖入代碼是不能自我修改的代碼,他在執(zhí)行期間不會改變猾编。因此兩個或者多個進程可以同時執(zhí)行相同的代碼瘤睹。每個進程都有自己的寄存器和數(shù)據(jù)存儲,以保證數(shù)據(jù)的正確性和安全答倡。
所以在物理內(nèi)存中只需要保存一個編輯器的副本轰传,每個用戶的頁表映射到編輯器的同一個物理副本,但是數(shù)據(jù)頁映射到不同的幀瘪撇。因此支持40個用戶获茬,只需要一個編輯器副本,和40個50k的數(shù)據(jù)空間倔既,所以只需要2150k,而不是8000k恕曲。