【OS学习笔记】十七 保护模式五:保护模式下如何进行内存保护 与 别名段的意义与作用
上一篇文章學(xué)習(xí)了如何進(jìn)入保護(hù)模式,以及如何在保護(hù)模式下進(jìn)行內(nèi)存訪問。點擊鏈接查看上一篇文章:進(jìn)入保護(hù)模式與在保護(hù)模式下訪問內(nèi)存
首先說明本片文章有對應(yīng)的匯編代碼,點擊鏈接查看:點擊查看
本篇文章接著學(xué)習(xí)。我們已經(jīng)知道了在保護(hù)模式下的內(nèi)存訪問的步驟:包括創(chuàng)建GDT,安裝段描述符,然后訪問GDT從中取得描述符的索引傳送給段寄存器的段選擇器從而形成段選擇子,然后根據(jù)段選擇子找到位于GDT中的描述符進(jìn)行段的訪問。那么第一次找到段描述符后就將其緩存到段寄存器的描述符高速緩存器中,在這之后的訪問中,直接從段寄存器的描述符高速緩存器中獲取描述符的基地址即可。
上述的步驟是我們之前學(xué)過的內(nèi)容。那么處理器是如何在這個過程中保證對內(nèi)存的訪問是安全的呢?如何確保訪問各個段的時候不會超出各個段的范圍?如何確定代碼段是不可寫的?如何確定要訪問的地址是否是有效的等這些問題,就是本文的學(xué)習(xí)目標(biāo)。
本文大概學(xué)習(xí)以下幾種保護(hù):
-
修改段寄存器時的保護(hù)
-
地址變換時的保護(hù)
- 代碼段執(zhí)行時的保護(hù)
- 棧操作時的保護(hù)
- 數(shù)據(jù)訪問時的保護(hù)
以及使用別名段來實現(xiàn)對代碼段的讀寫控制。
1、修改段寄存器時的保護(hù)
隨著程序的執(zhí)行,經(jīng)常會對段寄存器進(jìn)行修改。尤其是類似于jmp , call ,ret , iret這樣的指令就會隱式的修改段寄存器。
比如 jmp dword 0x0010:flush這條指令就會修改段寄存器(這條指令在下一篇文章中的55行)。
在完成以上指令的時候,處理器會將指令中給出的段選擇子傳給段寄存器的段選擇器。但是在傳送之前,寄存器會檢查段選擇子的正確性,并且需要確定該選擇子所對應(yīng)的描述符也是合法的。
假設(shè)我們的描述符就在GDT中(后面還會有LDT)。那么我們的段選擇子所對應(yīng)的描述符應(yīng)該完全位于GDT中。什么意思呢?看下圖:
我們可以看到,描述符位于GDT中,而且描述符的上邊界也要位于GDT 的上邊界內(nèi)。條件就是:索引號X8+7<= 邊界 這就是處理器做的檢查,如果這個條件不滿足,處理器就會產(chǎn)生一個異常中斷13,同時段寄存器中的原來的值不變。
以上僅僅是檢查的第一步。要是通過了上述檢查,并從GDT中獲取描述符后,緊接著還要對描述符的類別進(jìn)行確認(rèn)。如果描述符是只執(zhí)行代碼,則不允許加載到除CS之外的其他段寄存器中。
具體描述符的屬性,前幾篇文章已經(jīng)介紹,可以參考這篇文章中關(guān)于描述符的TYPE字段的含義:段描述符
在根據(jù)以上檢測出來該描述符所描述的段的屬性后,再檢查是否與我們要使用的段的用途匹配。具體規(guī)則如下表:
最后,除了檢查段的類別外,還要檢查描述符中的P位。如果P=0,表明雖然描述符已經(jīng)被定義,但是該段實際上并沒有存在于物理內(nèi)存中。此時,處理器終止處理,引發(fā)異常中斷11。中斷處理程序會把把該描述符所對應(yīng)的段從硬盤的調(diào)入內(nèi)存,然后置P為。 如果P=1,則處理器將描述符加載到段寄存器的的描述高速緩存器,同時置A位。
一旦上述規(guī)則全部通過,處理器就將選擇子加載到段寄存器的段選擇器。
2、地址變換時的保護(hù)
2.1 代碼段執(zhí)行時的保護(hù)
在32位模式下,盡管段的信息在描述符表中,但是,一旦相應(yīng)的描述符被加載到段寄存器的描述符高速緩存器后,則處理器取指令和執(zhí)行指令時,將不再訪問描述符表,而是直接使用段寄存器的描述符高速緩存寄存器,從中取出段的線性基地址,與EIP指針寄存器相加,得到最終的物理地址,從而取得指令。
不過,在正式開始執(zhí)行指令之前,處理器必須檢查這個地址的有效性,以防止執(zhí)行超出允許范圍的指令。
這個檢查與段的界限有關(guān)。訪問的指令不超過段的界限即可(與上面不超過GDT的界限一樣)。需要訪問的內(nèi)存地址加上指令的長度-1不超過段的界限。假設(shè)現(xiàn)在有如下圖的一個代碼段,地址范圍如下,那么EIP+指令長度-1要在下屬代碼段的地址范圍之內(nèi):
2.2 、棧操作時的保護(hù)
同上所述,在訪問棧段的時候,也是需要檢查指令是否合法。只不過與上述代碼段不同的是棧段一般是向下擴(kuò)展的段,所以在計算范圍的時候有一定區(qū)別:
2.3 數(shù)據(jù)訪問時的保護(hù)
與上述代碼段類似,在數(shù)據(jù)段訪問數(shù)據(jù)的時候,也是需要檢查地址的范圍是否合法。我們大概明白這其中的道理即可,不再贅述。
3、使用別名訪問代碼段
眾所周知,代碼段是不可寫的。那么如果我們想要寫代碼段,如何實現(xiàn)呢?
我們知道,訪問代碼段是使用CS寄存器保存段基地址,加上EIP寄存器存的值,就形成最終的物理地址,即可。
如果我們非要想寫代碼段的內(nèi)容,可以建立代碼段的別名。比如讓DS指向CS,那么當(dāng)我們操作DS寄存器的時候,雖然看上去是在操作數(shù)據(jù)段,實際上我們是在操作代碼段。比如我們下一篇文章就有對CS的別名DS,最后我們操作DS來修改代碼段的內(nèi)容!!!
4、總結(jié)
- 學(xué)習(xí)處理器是如何對內(nèi)存進(jìn)行保護(hù)
- 了解別名的意義與作用
筆記記得不是很全,如果有不懂的可以加我聯(lián)系方式一起交流。
學(xué)習(xí)探討加個人:
qq:1126137994
微信:liu1126137994
總結(jié)
以上是生活随笔為你收集整理的【OS学习笔记】十七 保护模式五:保护模式下如何进行内存保护 与 别名段的意义与作用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java程序员的求职面试简历应该怎么写?
- 下一篇: 电脑常见故障处理_彩超常见故障及维修