段选择符和段寄存器
? ? 8086中有4個16位的段寄存器:CS、DS、SS、ES,分別用于存放可執行代碼的代碼段、數據段、堆棧段和其他段的基地址。
? ? 80X86為段部分提供了6個存放段選擇符的段寄存器:CS、DS、ES、SS、FS和GS,但是,這些段寄存器中存放的不再是某個段的基地址,而是某個段的選擇符(Selector)。因為16位的寄存器無法存放32位的段基地址,段基地址只好存放在一個叫做描述符表(Descriptor)的表中。因此,在80X86中,我們把段寄存器叫做選擇符。
其中CS總是用于尋址代碼段,而堆棧段則專門使用SS段寄存器。
在任何指定時刻由CS尋址的斷稱為當前代碼段,此時EIP寄存其中包含了當前代碼段內下一條要執行指令的段內偏移地址,因此要執行指令的地址可表示成CS:[EIP]。
由段寄存器SS尋址的段稱為當前堆棧段,棧頂由ESP寄存器內容指定,因此堆棧頂處地址是SS:[ESP]。
另外4個段寄存器是通用段寄存器,當指令中沒有指定所操作數據的段時,那么DS將是默認的數據段寄存器。
以下來自對選擇符和描述符的介紹:http://www.kerneltravel.net/kernel-book/第二章%20Linux運行的硬件基礎/2.3.5.htm
在實模式下,段寄存器存儲的是真實的段地址,在保護模式下,16位的段寄存器無法放下32位的段地址,因此,它們被稱為選擇符,即段寄存器的作用是用來選擇描述符。選擇符的結構如圖2.16所示:? ? ? ? ? ? ??
???????????圖?2.16選擇符的結構(Segment Selector)
可以看出,選擇符有三個域:第15~3位這13位是索引域,表示的數據為0~8129,用于指向全局描述符表中相應的描述符。第二位為選擇域,如果TI=1,就從局部描述符表中選擇相應的描述符,如果TI=0,就從全局描述符表中選擇描述符。第1、0位是特權級,表示選擇符的特權級,被稱為請求者特權級RPL(Requestor Privilege Level)。只有請求者特權級RPL高于(數字低于)或等于相應的描述符特權級DPL,描述符才能被存取,這就可以實現一定程度的保護。
我們知道,實模式下是直接在段寄存器中放置段基地址,現在則是通過它來存取相應的描述符來獲得段基地址和其它信息,這樣以來,存取速度會不會變慢呢?為了解決這個問題,386的每一個段選擇符都有一個程序員不可見(也就是說程序員不能直接操縱)的88位寬的段描述符高速緩沖寄存器與之對應。無論什么時候改變了段寄存器的內容,只要特權級合理,描述符表中的相應的8字節描述符就會自動從描述符表中取出來,裝入高速緩沖寄存器中(還有24位其他內容)。一旦裝入,以后對那個段的訪問就都使用高速緩沖寄存器的描述符信息,而不會再重新從表中去取,這就大大加快了執行的時間,如圖2.17所示。
圖?2.17?段描述符高速緩沖寄存器的作用由于段描述符高速緩沖寄存器的內容只有在重新設置選擇符時才被重新裝入,所以,當你修改了選擇符所選擇的描述符后,必須對相應的選擇符重新裝入,這樣,88位描述符高速緩沖寄存器的內容才會發生變化。無論如何,當選擇符的值改變時,處理器自動裝載不可見部分。
下面講一下在沒有分頁操作時,尋址一個存儲器操作數的步驟:
1.?在段選擇符中裝入16位數,同時給出32位地址偏移量(比如在ESI、EDI中等等)
2.?根據段選擇符中的索引值、TI及RPL值,再根據相應描述符表寄存器中的段地址和段界限,進行一系列合法性檢查(如特權級檢查、界限檢查),該段無問題,就取出相應的描述符放入段描述符高速緩沖寄存器中。
段描述符(Segment Descriptor)通用格式如下圖:
3.?將描述符中的32位段基地址和放在ESI、EDI等中的32位有效地址相加,就形成了32位物理地址。
注意:在保護模式下,32位段基地址不必向左移4位,而是直接和偏移量相加形成32位物理地址(只要不溢出)。這樣做的好處是:段不必再定位在被16整除的地址上,也不必左移4位再相加。
尋址過程如圖?2.18所示。
總結
- 上一篇: 操作系统开发系列—2.进入32位保护模式
- 下一篇: Bochs安装FreeDOS与调试