我們還是先把**列出來吧,這樣比較容易說清楚:
label_seg_code32: ;從實模式跳轉到此進入保護模式
mov ax, selectordata ;資料段選擇子
mov ds, ax
mov ax, selectortest ;測試段選擇子
mov es, ax
mov gs, ax
mov ax, selectorstack ;堆疊段選擇子
mov ss, ax
mov esp, topofstack
jmp selectorcode16:0
[segment .s16code]
align 32
[bits 16]
label_seg_code16:
mov ax, selectornormal
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov eax, cr0
and al, 11111110b
mov cr0, eax
label_go_back_to_real:
jmp 0:label_real_entry
我們可以看到,前面那個jmp並沒有直接跳轉到實模式,而是選擇跳轉到乙個保護模式下的16位**段,在16位保護模式**段下的jmp才真正跳入到實模式。
那麼,你也許會問,為什麼要這麼麻煩,我們在實模式下不是直接從16位**段跳到32位**段的保護模式下了麼,那為什麼從保護模式就不能直接跳回去呢?
弄明白這個問題很重要,下面我們慢慢詳解。
我們還是先來搞清楚乙個概念:段描述符高速緩衝暫存器。
在實模式下,段暫存器含有段值,為訪問儲存器形成實體地址時,處理器引用相應的某個段暫存器並將其值乘以16,形成20位的段基位址。在保護模式下,段暫存器含有段選擇子,如上所述,為了訪問儲存器形成線性位址時,處理器要使用選擇子所指定的描述符中的基位址等資訊。為了避免在每次儲存器訪問時,都要訪問描述符表而獲得對應的段描述符,從80286開始每個段暫存器都配有乙個高速緩衝暫存器,稱之為段描述符高速緩衝暫存器或描述符投影暫存器,對程式設計師而言它是不可見的。每當把乙個選擇子裝入到某個段暫存器時,處理器自動從描述符表中取出相應的描述符,把描述符中的資訊儲存到對應的高速緩衝暫存器中。此後對該段訪問時,處理器都使用對應高速緩衝暫存器中的描述符資訊,而不用再從描述符表中取描述符。
各段描述符高速緩衝暫存器在實模式時之內容如下表所示:
這些高速緩衝暫存器在實方式下仍發揮作用,只是內容上與保護模式下有所不同。如上表所示,其中「y」表示「是」; 「n」表示「否」;「b」表示位元組;「u」表示向上擴充套件,「w」表示以字方式操作堆疊。段基位址仍是 32位,其值是相應段暫存器值(段值)乘以16,在把段值裝載到段暫存器時重新整理。由於其值是16位段值乘上16,所以在實模式下基位址實際上有效位只有 20位。每個段的32位段界限都固定為0ffffh,段屬性的許多位也是固定的。所謂固定是指在實方式下不可設定這些屬性值,只能繼續沿用保護方式下所設定的值。因此,在準備結束保護模式回到實模式之前,要通重載入乙個合適的描述符選擇子到有關段暫存器,以使得對應段描述符高速緩衝暫存器中含有合適的段界限和屬性。gdt中的描述符normal就是這樣乙個描述符,在返回實模式之前把對應選擇子normal載入到ds和es就是此目的。
接下來又乙個問題,在16位保護模式下的**段中的jmp怎麼這麼怪:
label_go_back_to_real:
jmp 0:label_real_entry
咦?段位址為什麼是0阿?!
其實這裡只是暫時這麼寫罷了,我們在程式的更前方(還在實模式下的時候)有這樣一段段**:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0100h
mov [label_go_back_to_real + 3], ax
說明保護模式下的長跳轉是5個位元組長,且後兩個位元組是段基址,而這最後一句恰恰是將實模式下的段基址裝入byte 4和byte 5。因此執行jmp 0:label_real_entry其實是變成了jmp cs_real_mode:label_real_entry。
再次漫遊(getting Started)
去年的今天,有個學長找我,問我有沒有興趣參加乙個軟體大賽,初到大一的我很感興趣,於是參加了這樣的乙個比賽,選擇的題目是虛擬漫遊,雖然經過了1個學期的努力,但是我們沒有成功的完成作品,主要處在乙個技術問題的解決上,就是mdl檔案的讀取與匯入上。今年,還是那個學長,又問我參不參加,我本來拒絕了,但是導師...
再次聽古箏
以前高中的時候和剛上大學的時候最喜歡聽古箏之類的古典 了,那時囊中羞澀,乙個星期也就十塊錢的生活費 那時物價真便宜啊!卻還剩下吃喝買上幾盒古典 的磁帶,放到隨身聽裡一遍遍不厭倦的聽!看到一幅彈古箏的美人圖,簡直都要很喜歡的。可是後來心的浮躁,已經很久不再聽了。有一次公司培訓,給我們放了一段古箏,是竹...
不要再次跌倒
1.核心中不能再中斷下使用sleep之類的函式,這樣會使cpu空等,而降低效率。2.時刻注意異常退出使用return的時候,是否把所有的該釋放的資源都釋放了!此處可以在發生異常後使用goto,跳轉到函式尾部用於釋放資源的 段!3.盡量不要使用鍊錶之類的需要動態申請記憶體的資料結構,直接使用乙個大記憶...