初识保护模式
書(shū)本第三章第一節(jié)是《認(rèn)識(shí)保護(hù)模式》,初步講解了保護(hù)模式下全局描述符表GDT、段描述符、段選擇子、從實(shí)模式進(jìn)入保護(hù)模式等內(nèi)容。去年看這個(gè)的時(shí)候,如果不是有以前學(xué)習(xí)保護(hù)模式時(shí)做的筆記,還真不好懂呢,因?yàn)樽髡咛峁┑牟牧喜粔蛳到y(tǒng),對(duì)僅學(xué)習(xí)過(guò)8086匯編語(yǔ)言的人來(lái)說(shuō),是不太好理解的。下面的內(nèi)容大體以我以前做的筆記為綱,較為簡(jiǎn)略,只說(shuō)明要點(diǎn)。(本來(lái)還可以參考下以前學(xué)習(xí)保護(hù)模式時(shí)收集的資料的,很可惜,移動(dòng)硬盤壞了,資料都沒(méi)有了,早就該注意信息安全了的。)
- 描述符與描述符表
???? 8086是16位處理器,有16位的寄存器和數(shù)據(jù)總線,20位的地址總線,尋址能力為1MB。地址由段基址和段偏移兩部分組成,段基址和偏移地址都是16 位的,物理地址的計(jì)算方式為:物理地址=段基址×16+段偏移。從80386開(kāi)始,Intel處理器進(jìn)入了32位時(shí)代,地址總線為32位,尋址能力為 4GB。此時(shí),通用寄存器變成從16位變成了32位,但段寄存器仍然是16位的,原來(lái)的基地址加偏移值的物理地址計(jì)算方法已經(jīng)不適用了,需要新的計(jì)算方法。
??? 386以上CPU運(yùn)行于保護(hù)模式時(shí),雖然段寄存器仍然是16位的,但是其意義已經(jīng)發(fā)生了變化:不再是表示段基地址了,而是表示段描述符在描述符表中的索引。此時(shí),段寄存器的值也有了一個(gè)新的名稱:段選擇子。
?????? 段描述符是描述段屬性的一個(gè)8字節(jié)數(shù)據(jù)結(jié)構(gòu),分為三種類型:(數(shù)據(jù)段和代碼段)段描述符、系統(tǒng)段描述符和門描述符。書(shū)本第43頁(yè)給出了描述符的結(jié)構(gòu)圖。書(shū)中說(shuō)“由于歷史問(wèn)題,它們(描述符中的段基址和段偏移)都被拆開(kāi)存放”。我想,這個(gè)歷史問(wèn)題是指為兼容80286處理器的設(shè)計(jì)吧:80286采用24位地址線,尋址能力16MB,所以段基址被拆開(kāi)成低24位和高8位兩部分;80286已經(jīng)引入“保護(hù)模式”的概念,是推出實(shí)模式和保護(hù)模式CPU的分水嶺。附兩個(gè)粗略介紹80286的網(wǎng)址:http://wiki.ccw.com.cn/80286?,http://baike.baidu.com/view/193778.htm
????? 描述符表是內(nèi)存中保存一個(gè)或者多個(gè)描述符的區(qū)域,由相關(guān)寄存器(GDTR、LDTR、IDTR)指示其起始地址。有三種描述符表:
????? GDT Global Description Table 全局描述符表
????? LDT Local Description Table? 局部描述符表
????? IDT Interrupt Description Table 中斷描述符表
????? 段選擇子是段寄存器的內(nèi)容。雖然386處理器中段寄存器還是16位的,但是在保護(hù)模式下,其內(nèi)容的意義已經(jīng)發(fā)生了變化,不再是表示段基地址,而是表示段描述符在描述符表中的位置。其中第0位和第1位是RPL(Request Privilege Level 請(qǐng)求特權(quán)級(jí)),用以進(jìn)行訪問(wèn)權(quán)限檢查,這個(gè)以后再詳細(xì)描述;第2位是TI(Task Indication,任務(wù)指示),其值為0表示使用GDT,為1表示使用LDT;第3至15位是段描述符在相應(yīng)的描述符表中的索引。
- 存儲(chǔ)器尋址
???? 實(shí)模式下的尋址方式同8086:段基地址×16+段偏移地址。
???? 保護(hù)模式下使用48位地址指針:16位段選擇子和32位段偏移地址。尋址過(guò)程為:從相應(yīng)的段寄存器中取出段選擇子,根據(jù)高13位從相應(yīng)的描述符表中取得段描述符;用段描述符給出的32位段基地址,加上32位的偏移地址得到32位線性地址;如果沒(méi)有啟用分頁(yè),則32位線性地址就是物理地址,否則線性地址再經(jīng)過(guò)分頁(yè)機(jī)制轉(zhuǎn)化成物理地址。當(dāng)然,尋址過(guò)程中會(huì)根據(jù)段描述符給出的段屬性進(jìn)行各種檢查,如特權(quán)級(jí)檢查、地址越界檢查、段頁(yè)是否存在檢查等。
- 寄存器模型
?? 我覺(jué)得,沒(méi)有給出386的寄存器模型是本書(shū)的一大缺憾。這里給出386的寄存器模型并作簡(jiǎn)要說(shuō)明。(這張圖我花了好長(zhǎng)時(shí)間用WPS Office畫(huà)的)
???
?????? 圖中陰影部分是實(shí)模式下可用的寄存器。
?????? EAX、EBX、ECX、EDX:8086中的通用寄存器已經(jīng)擴(kuò)展成32位的了。當(dāng)然,還是可以使用AX、BX、CX、DX訪問(wèn)低16位;或者用AH、AL等分別訪問(wèn)低16位的高低兩個(gè)字節(jié)。
?????? CS、DS、SS、ES、FS、GS:新增了FS和GS這兩個(gè)16位的段寄存器。CS、DS、SS、ES的用途不變,還是代碼段、數(shù)據(jù)段、堆棧段和擴(kuò)展段寄存器;FS和GS也可以看作是方便程序員使用的擴(kuò)展段寄存器。
?????? EIP:地址變成32位了,指令指針當(dāng)然也要擴(kuò)展成32位的了。
?????? ESP、EBP、ESI、EDI:堆棧指針、基址指針、源變址、目標(biāo)變址寄存器,名字前面加上字母E表示擴(kuò)展成32位了。
?????? EFLAGS:標(biāo)志寄存器也變成32位的了。
?????? 以下是386新增的寄存器:
?????? IDTR、GDTR和LDTR:IDTR和GDTR是48位的,分別用以保存中斷描述符表和全局描述符表的基地址(32位)和限長(zhǎng)(16位)。LDTR保存局部描述符的段選擇子,其使用方式為:1 在LDTR中裝入段選擇子,CPU自動(dòng)從GDT中取出局部描述符,放入高速緩存中,為當(dāng)前任務(wù)建立LDT;2 以后使用段寄存器中的選擇子時(shí),若發(fā)現(xiàn)TI位為1,則從LDT中找到相應(yīng)的段描述符進(jìn)行尋址操作。
?????? TR:任務(wù)寄存器,存放任務(wù)狀態(tài)段選擇子,指示任務(wù)狀態(tài)段描述符在GDT中的位置(類似LDTR)。使用方式類似LDTR:在TR中裝入段選擇子,CPU 自動(dòng)從GDT中取出任務(wù)狀態(tài)段描述符,放入高速緩存中,為當(dāng)前任務(wù)建立TSS。TSS是Task State Segment(任務(wù)狀態(tài)段)的簡(jiǎn)寫(xiě),它定義了啟動(dòng)任務(wù)所需要的信息,簡(jiǎn)言之(不太準(zhǔn)確),就是一個(gè)進(jìn)程的相關(guān)信息。
?????? CR0、CR1、CR2、CR3、CR4:控制寄存器,保存了系統(tǒng)的各種標(biāo)志位。其中CR0的低16位就是8086中的MSW(Machine State Word,機(jī)器狀態(tài)字)。這里需要關(guān)注的是CR0的第0位PE標(biāo)志,其值為0表示當(dāng)前運(yùn)行在實(shí)模式下;為1表示運(yùn)行于保護(hù)模式下。
- 進(jìn)入保護(hù)模式
??? 書(shū)本上給出了進(jìn)入保護(hù)模式的代碼,還有詳細(xì)的說(shuō)明,我就不給自己的代碼了,只對(duì)一個(gè)地方進(jìn)行簡(jiǎn)要說(shuō)明:為什么要在GDT的起始位置處定義一個(gè)沒(méi)有使用的空的描述符???
??? 這個(gè)問(wèn)題我想了好久也沒(méi)想通,后來(lái)在網(wǎng)上找到了答案:GDT中索引為0的描述符是特殊的空描述符,是不能使用的,如果使用它進(jìn)行存儲(chǔ)器訪問(wèn),會(huì)引發(fā)Genernal Protection異常。關(guān)于這個(gè)問(wèn)題,可以參考http://leonstar.bokee.com/36918.html
總結(jié)
- 上一篇: 两张图看懂GDT、GDTR、LDT、LD
- 下一篇: 保护模式