版權(quán)歸原作者所有,如有侵權(quán),請聯(lián)系我們

[科普中國]-x86內(nèi)存分段

科學百科
原創(chuàng)
科學百科為用戶提供權(quán)威科普內(nèi)容,打造知識科普陣地
收藏

x86架構(gòu)中,存儲器分段(英語:Memory Segmentation)是在不改變16位段選擇符時,使用單個索引寄存器(保存了段內(nèi)地址偏移值)所能夠?qū)ぶ返牡拇鎯ζ鞣秶糠帧R仓冈谟⑻貭杧86指令集體系結(jié)構(gòu)下存儲器分段的實現(xiàn)方式。1

歷史1978年的Intel 8086開始引入了內(nèi)存分段。這使得16位CPU可以訪問超過64 KB (65,536字節(jié))的內(nèi)存,實際上8086 CPU到內(nèi)存的地址總線是20位,即可訪問2=1MB內(nèi)存。在16位模式,要讓應(yīng)用程序使用多個存儲器分段(為了訪問比任一64K分段還要大的存儲器)是相當復雜。這個問題的根源在于沒有適當?shù)倪m合做整個存儲器范圍的平面尋址的地址算術(shù)指令。平面尋址方式也可以乘法指令來完成,但這會導致較慢的程序運行速度。

1982年面世的80286處理器的實模式與保護模式,以及80386及其后的處理器的虛擬86模式,一個分段的大小是64KiB(使用16位索引寄存器)。在Intelx86的實模式下的分段架構(gòu)的內(nèi)存空間會有所重疊,這是一種不好的設(shè)計。 80286的保護模式下,16位的段寄存器中的13位(稱作段選擇符segment selector)是描述符表的條目(descriptor table entry)的索引;該條目包含了24位的段開始地址以及16位的段長度;段開始地址與段內(nèi)偏移地址相加即為內(nèi)存物理地址。16位段寄存器中的剩余3位分別是全局/局部描述符表指示位、請求特權(quán)級(request privilege level)。

1985年面世的80386及其后續(xù)處理器的32位保護模式下,一個分段長度上限是2個粒度單位,粒度可以是1字節(jié)或4K字節(jié),因此分段長度上限可以是4GB,這與索引寄存器是32位相配合。

隨著32位操作系統(tǒng)的推出,以及更舒適的32位平面存儲器模式,到1990年末期幾乎淘汰了使用分段尋址。然而,使用32位平面存儲器模式產(chǎn)生的最多只能訪問4GB地址空間的限制并沒有遠離日常的使用。分段允許操作系統(tǒng)對每個進程虛擬尋址空間的限制,最大可利用64GB的系統(tǒng)存儲器,但這種最終回歸到分段的尷尬,經(jīng)常被引述為朝著64位處理器發(fā)展的動機。

2003年問世的x86-64架構(gòu)下,強制實現(xiàn)了平面內(nèi)存模型,但保留了使用段寄存器FS或GS的64位下的分段尋址。

實模式實模式與虛擬86模式下,一個段總是長64,536字節(jié)(16位段內(nèi)偏移地址)。在段寄存器內(nèi)的16位段選擇符(segment selector)被解釋為20位線性地址空間的高16位,稱為段地址;其余的低4位全為0。段地址與16位段內(nèi)偏移地址相加產(chǎn)生線性地址,同時也是這種內(nèi)存模式下的物理地址。 任何程序都可以訪問全部內(nèi)存空間。沒有對內(nèi)存的訪問權(quán)限保護。

80286保護模式Intel 80286處理器仍然使用16位段寄存器與16位的段內(nèi)偏移地址,但保護模式下支持訪問2(16M)字節(jié)的內(nèi)存。16位段寄存器內(nèi)不再是段地址,16位段寄存器的高13位被稱作段選擇符(segment selector),其值是到段描述符表的索引值。段描述符中包含了24位的段開始的基地址,20位的段長度。段開始地址與段內(nèi)偏移地址相加即為內(nèi)存物理地址。段的長度上限為2=1M字節(jié)。

80386保護模式Intel 80286處理器繼續(xù)使用286的分段保護模式,但段描述符中包含了32位的段開始的基地址。段內(nèi)偏移地址也是32位。在分段轉(zhuǎn)址與物理地址之間又增加了一層分頁(paging)轉(zhuǎn)址。分段尋址是不能關(guān)閉的。分頁可以使能或關(guān)閉(enabled or disabled),如果關(guān)閉就與286保護模式一樣。如果使用分頁機制,則由段開始的基地址與段內(nèi)偏移地址相加得到的是線性地址(虛地址),線性地址還需要分頁轉(zhuǎn)址才得到內(nèi)存物理地址。

386處理器增加了兩個段寄存器FS、GS,這兩個寄存器并無硬件綁定的用途。Windows操作系統(tǒng)在地址FS:0中保存了當前線程信息塊。Linux中GS指向了線程局部存儲。

通過清除控制寄存器CR0中的最低位,可由386保護模式轉(zhuǎn)為實模式。

Linux操作系統(tǒng)在386保護模式下把段基址設(shè)為0,段長度設(shè)為4GiB,從而模擬了平面內(nèi)存模型。

x86-64的64位模式在x86-64體系結(jié)構(gòu)64位的long mode,段寄存器CS, SS, DS, ES強制為0。段長度強制為2。形式上還有內(nèi)存分段,但實際上所有內(nèi)存都在唯一的一個分段中。段寄存器FS、GS可以有非0值,被操作系統(tǒng)用于其它用途。即硬件支持如“FS:[RAX]”這樣的寄存器間接尋址。

本詞條內(nèi)容貢獻者為:

王沛 - 副教授、副研究員 - 中國科學院工程熱物理研究所