回覆列表
  • 1 # 使用者7978797415036

    沒記錯的話,很久很久以前,計算機沒什麼保護,資料訪問(實際上就是記憶體裡面的內容啦)都是直接給一個地址就行,反正那個時代,計算機也不是非常複雜,能幹的事情也就那幾樣吧。

    然後,計算機進化了一下,資料地址不再直接給出來了,而是透過段+偏移計算出來。一個典型的場景就是指令獲取,透過cs:ip計算。cs是程式碼段暫存器,裡面的內容是程式碼段的物理地址,ip是指令相對cs段暫存器的偏移地址。

    大概是80年代吧,計算機又進化了,這次開始出現所謂的保護模式了。顧名思義,有些東西不能隨便用了,被保護起來了,想要訪問的話,必須得有許可權才行。那麼被保護的東西是什麼呢?從系統層面看,主要就是記憶體的位置,有些位置存的東西比較敏感,不能隨便訪問。比如核心空間裡面儲存的資料,就不是隨便能訪問的。

    但是記憶體看起來好像並沒有那麼明顯的特權劃分。就好像一條馬路,我們走著走著,突然前面不讓走了,比如設定了路障什麼的。但是記憶體好像並沒有什麼特殊路障啊。比如地址0的位置存的是普通資料,地址100處存的是敏感資料,我們如何實現類似路障的效果呢?

    理論上實現方法有很多種,intel的實現方案是:透過段暫存器來實現。前面說過,最早是沒有段暫存器的,段暫存器是後來才出現的。段暫存器出現之後記憶體地址計算方式出現了變化,即按照段+偏移進行計算,且段暫存器裡面存的是段的真實起始地址。但是保護模式下,段暫存器又變了,不再存段的真實地址,而是透過一種間接的方式來獲得真實地址,這時段的真實地址被抽取出來,存在所謂的GDT或LDT中,而段暫存器改為儲存記憶體所在段在GDT或LDT中的索引值(也就是陣列下標,因為GDT/LDT從結構上看就是個陣列)。這裡先不糾結GDT/LDT是什麼,長什麼樣子,只要知道它裡面存了段地址(基址)就行。重點:這時段暫存器最高13位用來存索引值,而最低3位被保留,其中最低2位用來存許可權等級,0級最大,3級最小(注:段暫存器一直都是16位的)。可能你也看出來了,2位最多是4個級別,是的,但是作業系統,這裡指的是linux,只用了2個級別:0和3。

    下面說下保護模式,前面說過,記憶體地址是透過段+偏移計算出來的,其中段暫存器最低2位指明瞭特權等級,也就是當前訪問者的特權級別。而記憶體也是有等級的,如果你瞭解過記憶體管理,應該知道有頁表這麼個東西,頁表項裡面也有特權級的,這裡不展開了。現在就比較有意思了,訪問者(即段暫存器+偏移)是有特權級的,被訪問者(即記憶體,特權級別存在對應的頁表項中)也是有特權級的,一般而言,訪問者的特權級別一定要大於等於被訪問者的特權級別,也就是說暫存器中的特權級別必須大於或等於頁表項中的特權等級。

    舉個例子就是,大家都知道很多資料都是有密級的,大boss可以檢視密級很高的資料,而普通人只能看密級很低的資料。

    大概就是這麼個理解。

    至於使用者棧和核心棧,首先程式執行時是需要一段記憶體來儲存執行時資料的,比如區域性變數,這個記憶體就是所謂的棧。保護模式下,使用者態的程式碼是不能訪問核心的資料的,否則就像誰都可以進你家裡一樣,很容易被人惡意利用。但是程式執行一定要一個棧的,所以核心態和使用者態各自有自己的棧,就是所謂的核心棧和使用者棧。

    程序切換特權級別時,會自動切換棧的。

  • 中秋節和大豐收的關聯?
  • 活佛濟公有沒有第四部?