段選擇符用來表示指向哪個段描述符,即用來在段描述符中尋址,前13位是地址,能尋0到(2^13)-1,因此段描述符表的大小就是 8192,他還牽扯到一些特權級的限制,后三位;段描述符是用來表示這個段的一些性質的,比如段基址和段長之類的。我們在尋址的時候,一般是從段選擇符找 到段描述符,然后從段描述符中取出段基址,加上偏移就形成了我們要訪問的地址。
8086中有4個16位的段寄存器:CS、DS、SS、ES,分別用於存放可執行代碼的代碼段、數據段、堆棧段和其他段的基地址。
在 80386中,有6個16位的段寄存器,但是,這些段寄存器中存放的不再是某個段的基地址,而是某個段的選擇符(Selector)。因為16位的寄存器 無法存放32位的段基地址,段基地址只好存放在一個叫做描述符表(Descriptor)的表中。因此,在80386中,我們把段寄存器叫做選擇符。下面 給出6個段寄存器的名稱和用途:
CS 代碼段寄存器
DS 數據段寄存器
SS 堆棧段寄存器
ES、FS及GS 附加數據段寄存器
下面是對選擇符和描述符的介紹:(來自:www.kerneltravel.net/kernel-book/%E7%AC%AC%E4%BA%8C%E7%AB%A0%20Linux%E8%BF%90%E8%A1%8C%E7%9A%84%E7%A1%AC%E4%BB%B6%E5%9F%BA%E7%A1%80/2.3.5.htm)
選擇符與描述符表寄存器
在實模式下,段寄存器存儲的是真實的段地址,在保護模式下,16位的段寄存器無法放下32位的段地址,因此,它們被稱為選擇符,即段寄存器的作用是用來選擇描述符。選擇符的結構如圖2.16所示:
圖 2.16選擇符的結構
可 以看出,選擇符有三個域:第15~3位這13位是索引域,表示的數據為0~8192,用於指向全局描述符表中相應的描述符。第二位為選擇域,如果 TI=1,就從局部描述符表中選擇相應的描述符,如果TI=0,就從全局描述符表中選擇描述符。第1、0位是特權級,表示選擇符的特權級,被稱為請求者特權級RPL(Requestor Privilege Level)。只有請求者特權級RPL高於(數字低於)或等於相應的描述符特權級DPL,描述符才能被存取,這就可以實現一定程度的保護。
我 們知道,實模式下是直接在段寄存器中放置段基地址,現在則是通過它來存取相應的描述符來獲得段基地址和其它信息,這樣以來,存取速度會不會變慢呢?為了解 決這個問題,386的每一個段選擇符都有一個程序員不可見(也就是說程序員不能直接操縱)的88位(8*8+24)寬的段描述符高速緩沖寄存器與之對應。 無論什么時候改變了段寄存器的內容,只要特權級合理,描述符表中的相應的8字節描述符就會自動從描述符表中取出來,裝入高速緩沖寄存器中(還有24位其他 內容)。一旦裝入,以后對那個段的訪問就都使用高速緩沖寄存器的描述符信息,而不會再重新從表中去取,這就大大加快了執行的時間,如圖2.17所示
圖 2.17 段描述符高速緩沖寄存器的作用
由於段描述符高速緩沖寄存器的內容只有在重新設置選擇符時才被重新裝入,所以,當你修改了選擇符所選擇的描述符后,必須對相應的選擇符重新裝入,這樣,88位描述符高速緩沖寄存器的內容才會發生變化。無論如何,當選擇符的值改變時,處理器自動裝載不可見部分。
下面講一下在沒有分頁操作時,尋址一個存儲器操作數的步驟:
1. 在段選擇符中裝入16位數,同時給出32位地址偏移量(比如在ESI、EDI中等等)
2. 根據段選擇符中的索引值、TI及RPL值,再根據相應描述符表寄存器中的段地址和段界限,進行一系列合法性檢查(如特權級檢查、界限檢查),該段無問題,就取出相應的描述符放入段描述符高速緩沖寄存器中。
4. 將描述符中的32位段基地址和放在ESI、EDI等中的32位有效地址相加,就形成了32位物理地址。
注意:在保護模式下,32位段基地址不必向左移4位,而是直接和偏移量相加形成32位物理地址(只要不溢出)。這樣做的好處是:段不必再定位在被16整除的地址上,也不必左移4位再相加。
尋址過程如圖 2.18所示。