因為cpu在實模式下位址匯流排為20位,所以能訪問到的內存在1m左右,為了能操作更多的記憶體,cpu生產商設計了保護模式,在此模式下匯流排位址可達32位,訪問記憶體明顯增加。
用保護模式來32位定址的操作要用乙個叫gdt的東西,這個gdt(global descriptor table)叫全域性描述表。我對它的理解是它像乙個目錄,每一條存著在記憶體裡的乙個段的頭位址和這個段的大小。
這個段就理解為在記憶體中選取一小塊,給它起個名字,那麼他就是記憶體中的乙個段了。
下邊這個圖更好描述
當然gdt在記憶體中的位置肯定要在實模式可以訪問的範圍內。
當要訪問更大的位址的時候,要訪問某個段就先訪問該段在gdt中的條目,然後得到他的實際實體地址,啟動保護模式的32位匯流排訪問它。
move ax [0x5a1]
比方說實模式下想要把0x5a1位置的記憶體資料讀到ax暫存器中那麼用上邊那個彙編語句就行,當然先把基位址暫存器設為0.
要是要訪問5m位置的記憶體資料的話這種方式就行不通了,這時候要使用如下**
[section .gdt]
; 段基址 段界限 屬性
label_gdt: descriptor 0, 0, 0
label_desc_code32: descriptor 0, segcode32len - 1, da_c + da_32
label_desc_video: descriptor 0b8000h, 0ffffh, da_drw
label_desc_5m: descriptor 0500000h, 0ffffh, da_drw
gdtlen equ $ - label_gdt
gdtptr dw gdtlen - 1
dd 0
selectorcode32 equ label_desc_code32 - label_gdt
selectorvideo equ label_desc_video - label_gdt
selector5m equ label_desc_5m - label_gdt
mov bx, selector5m ;用 es 指向5m記憶體描述符
mov es, bx
mov edi, 0
mov ax, [es:edi]
第一塊**是對gdt的乙個編寫,在這個表中給在記憶體5m位置的段起了個名字叫label_desc_5m,大小為0ffffh。我還寫了其他的一些段,大家不要在意。
第二塊**就是使用了,其中selector5m相當於label_desc_5m這個段在gdt這個表裡是第幾條,這裡是第四條。把它通過bx暫存器傳遞給es暫存器。這個es暫存器就是專門來找gdt表中段的條目的。edi裡的值是相對於5m這個位置的偏移,要是訪問5m這個位置那麼edi置為0,要是訪問5m零1位元組那麼edi就置為1,以此類推,當然不能超過這個段的最大範圍。然後最後一句話就是把5m位置的資料寫入ax當中。
思考一下,若是用實模式的方法訪問5m記憶體那麼就是mov ax [0x500000],當然這個是執行不了的,暫存器和匯流排都不支援。
mov ax ,[es:edi]這句話可以看成mov ax [0x500000+0],他之所以能執行是因為這個[es:edi]引發了保護模式,應該是在es上定址的話會啟動保護模式讀取gdt訪問更大記憶體,這種實現是一種硬體實現。
總結為下面這個圖
進入保護模式
本文為 每個描述符佔8位元組,下圖中,上面位高32位,下面為低32位 disk boot ata channel 0 first hd cd on channel 0 type of disk image這個選項是vpc,我用2.6.2配置時選vpc無法啟動,得選flat才可以,2.6.0貌似選vp...
進入保護模式
以下圖2,圖4和圖5截自intel手冊 每個描述符佔8位元組,下圖中,上面位高32位,下面為低32位 disk boot ata channel 0 first hd cd on channel 0 type of disk image這個選項是vpc,我用2.6.2配置時選vpc無法啟動,得選fl...
進入保護模式總結
1.最主要的就是那個jmp dword,一切都是為了jmp做準備 2.int 13h讀取扇區,既可以讀硬碟,又可以讀軟盤,應該是兩個的驅動器號不同 這個還沒搞清楚,現在只會讀軟盤 用硬碟映像的時候,總是說找不到引導裝置,不知道是哪兒的引數錯了。一些細節 cl是讀取的扇區號,1就是第1個扇區,並不是從...