; 描述符圖示
; 圖示一
;
; ------ ┏━━━┳━━━━━┓高地址
; ┃ 7 段 ┃
; ┣━━━┫ ┃
; 基
; 字節(jié) 7 ┆ ┆ ┆
; 址
; ┣━━━┫ ② ┃
; ┃ 0 ┃
; ------ ┣━━━╋━━━━━┫
; ┃ 7 ┃ G ┃
; ┣━━━╉━━━──┨
; ┃ 6 ┃ D ┃
; ┣━━━╉━━━──┨
; ┃ 5 ┃ 0 ┃
; ┣━━━╉━━━──┨
; ┃ 4 ┃ AVL ┃
; 字節(jié) 6 ┣━━━╉━━━──┨
; ┃ 3 ┃ ┃
; ┣━━━┫ 段 ┃
; ┃ 2 ┃ 界 ┃
; ┣━━━┫ 限 ┃
; ┃ 1 ┃ ┃
; ┣━━━┫ ② ┃
; ┃ 0 ┃ ┃
; ------ ┣━━━╋━━━━━┫
; ┃ 7 ┃ P ┃
; ┣━━━╉━━━──┨
; ┃ 6 ┃ ┃
; ┣━━━┫ DPL ┃
; ┃ 5 ┃ ┃
; ┣━━━╉━━━──┨
; ┃ 4 ┃ S ┃
; 字節(jié) 5 ┣━━━━╉━━──┨
; ┃ 3 ┃ ┃
; ┣━━━━┫ T ┃
; ┃ 2 ┃ Y ┃
; ┣━━━━┫ P ┃
; ┃ 1 ┃ E ┃
; ┣━━━━┫ ┃
; ┃ 0 ┃ ┃
; ------ ┣━━━━╋━━━━┫
; ┃ 23 ┃ ┃
; ┣━━━━┫ ┃
; ┃ 22 ┃ ┃
; ┣━━━━┫ 段 ┃
;
; 字節(jié) ┆ ┆ 基 ┆
; 2, 3, 4
; ┣━━━━┫ 址 ┃
; ┃ 1 ┃ ① ┃
; ┣━━━━┫ ┃
; ┃ 0 ┃ ┃
; ------ ┣━━━━╋━━━━┫
; ┃ 15 ┃ ┃
; ┣━━━━┫ ┃
; ┃ 14 ┃ ┃
; ┣━━━━┫ 段 ┃
;
; 字節(jié) 0,1┆ ┆ 界 ┆
;
; ┣━━━━┫ 限 ┃
; ┃ 1 ┃ ① ┃
; ┣━━━━┫ ┃
; ┃ 0 ┃ ┃
; ------ ┗━━━━┻━━━━┛低地址
;
; 圖示二
; 高地址………………………………………………………………………低地址
; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
; |7654321076543210765432107654321076543210765432107654321076543210| <- 共 8 字節(jié)
; |--------========--------========--------========--------========|
; ┏━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓
; ┃31..24 ┃ (見下圖) ┃ 段基址(23..0) ┃ 段界限(15..0) ┃
; ┃ ┃ ┃ ┃ ┃
; ┃ 基址2 ┃ ③ │ ② │ ① ┃ 基址1b │ 基址1a ┃ 段界限1 ┃
; ┣━━━━━━━╋━━━━━━━┳━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━┫
; ┃ %6 ┃%5 ┃%4 ┃ %3 ┃ %2 ┃ %1 ┃
; ┗━━━┻━━━┻━━━┻━━━┻━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━┛
; │ \_________
; │ \__________________
; │ \________________________________________________
; │ \
; ┏━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┓
; ┃ 7 ┃ 6 ┃ 5 ┃ 4 ┃ 3 ┃ 2 ┃ 1 ┃ 0 ┃ 7 ┃ 6 ┃ 5 ┃ 4 ┃ 3 ┃ 2 ┃ 1 ┃ 0 ┃
; ┣━━━━╋━━━━╋━━━━╋━━━━╋━━━━┻━━━━┻━━━━┻━━━━╋━━━━╋━━━━┻━━━━╋━━━━╋━━━━┻━━━━┻━━━━┻━━━━┫
; ┃ G ┃D/B ┃ 0 ┃ AVL┃段界限 2 (19..16) ┃ P ┃ DPL ┃ S ┃ TYPE ┃
; ┣━━━━┻━━━━┻━━━━┻━━━━╋━━━━━━━━━━━━━━━━━━╋━━━━┻━━━━━━━━━━┻━━━━━┻━━━━━━━━━━━━━━━━━━┫
; ┃ ③: 屬性 2 ┃ ②: 段界限 2 ┃ ①: 屬性1 ┃
; ┗━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
; 高地址 低地址
;
;
; 說明:
;
; (1) P: 存在(Present)位职烧。
; P=1 表示描述符對地址轉(zhuǎn)換是有效的呵曹,或者說該描述符所描述的段存在,即在內(nèi)存中疙赠;
; P=0 表示描述符對地址轉(zhuǎn)換無效枫浙,即該段不存在。使用該描述符進(jìn)行內(nèi)存訪問時會引起異常刃鳄。
;
; (2) DPL: 表示描述符特權(quán)級(Descriptor Privilege level)盅弛,共2位。它規(guī)定了所描述段的特權(quán)級铲汪,
; 用于特權(quán)檢查熊尉,以決定對該段能否訪問。
;
; (3) S: 說明描述符的類型掌腰。
; 對于存儲段描述符而言狰住,S=1,以區(qū)別與系統(tǒng)段描述符和門描述符(S=0)齿梁。
;
; (4) TYPE: 說明存儲段描述符所描述的存儲段的具體屬性催植。
;數(shù)據(jù)段類型 類型值 說明
; ----------------------------------
; 0 只讀
; 1 只讀肮蛹、已訪問
; 2 讀/寫
; 3 讀/寫、已訪問
; 4 只讀创南、向下擴(kuò)展
; 5 只讀伦忠、向下擴(kuò)展、已訪問
; 6 讀/寫稿辙、向下擴(kuò)展
; 7 讀/寫昆码、向下擴(kuò)展、已訪問
;
;
;代碼段類型 類型值 說明
; ----------------------------------
; 8 只執(zhí)行
; 9 只執(zhí)行邻储、已訪問
; A 執(zhí)行/讀
; B 執(zhí)行/讀赋咽、已訪問
; C 只執(zhí)行、一致碼段
; D 只執(zhí)行吨娜、一致碼段脓匿、已訪問
; E 執(zhí)行/讀、一致碼段
; F 執(zhí)行/讀宦赠、一致碼段陪毡、已訪問
;
;
;系統(tǒng)段類型 類型編碼 說明
; ----------------------------------
; 0 <未定義>
; 1 可用286TSS
; 2 LDT
; 3 忙的286TSS
; 4 286調(diào)用門
; 5 任務(wù)門
; 6 286中斷門
; 7 286陷阱門
; 8 未定義
; 9 可用386TSS
; A <未定義>
; B 忙的386TSS
; C 386調(diào)用門
; D <未定義>
; E 386中斷門
; F 386陷阱門
;
; (5) G: 段界限粒度(Granularity)位。
; G=0 表示界限粒度為字節(jié)勾扭;
; G=1 表示界限粒度為4K 字節(jié)毡琉。
; 注意,界限粒度只對段界限有效尺借,對段基地址無效绊起,段基地址總是以字節(jié)為單位。
;
; (6) D/B: 此位是一個很特殊的位燎斩,在描述可執(zhí)行段、向下擴(kuò)展數(shù)據(jù)段或由SS寄存器尋址的段
蜂绎; (通常是堆棧段)的三種描述符中的意義各不相同栅表。
; ⑴ 在描述可執(zhí)行段的描述符中,D位決定了指令使用的地址及操作數(shù)所默認(rèn)的大小师枣。
; ① D=1表示默認(rèn)情況下指令使用32位地址及32位或8位操作數(shù)怪瓶,這樣的代碼段也稱為32位代碼段;
; ② D=0 表示默認(rèn)情況下践美,使用16位地址及16位或8位操作數(shù)洗贰,這樣的代碼段也稱為16位代碼段,
陨倡; 它與80286兼容敛滋。可以使用地址大小前綴和操作數(shù)大小前綴分別改變默認(rèn)的地址或操作數(shù)的大小兴革。
; ⑵ 在向下擴(kuò)展數(shù)據(jù)段的描述符中绎晃,D 位決定段的上部邊界蜜唾。
; ① D=1表示段的上部界限為4G;
; ② D=0表示段的上部界限為64K庶艾,這是為了與80286兼容袁余。
; ⑶ 在描述由SS寄存器尋址的段描述符中,D位決定隱式的堆棧訪問指令(如PUSH和POP指令)使用
咱揍; 何種堆棧指針寄存器颖榜。
; ① D=1表示使用32位堆棧指針寄存器ESP;
; ② D=0表示使用16位堆棧指針寄存器SP煤裙,這與80286兼容朱转。
;
; (7) AVL: 軟件可利用位。80386對該位的使用未左規(guī)定积暖,Intel公司也保證今后開發(fā)生產(chǎn)的處理器
藤为; 只要與80386兼容,就不會對該位的使用做任何定義或規(guī)定夺刑。
;
;----------------------------------------------------------------------------
; 描述符類型值說明
; 其中:
; DA_ : Descriptor Attribute
; D : 數(shù)據(jù)段
; C : 代碼段
; S : 系統(tǒng)段
; R : 只讀
; RW : 讀寫
; A : 已訪問
; 其它 : 可按照字面意思理解
;----------------------------------------------------------------------------
DA_32 EQU 4000h ; 32 位段
DA_DPL0 EQU 00h ; DPL = 0
DA_DPL1 EQU 20h ; DPL = 1
DA_DPL2 EQU 40h ; DPL = 2
DA_DPL3 EQU 60h ; DPL = 3
;----------------------------------------------------------------------------
; 存儲段描述符類型值說明
;----------------------------------------------------------------------------
DA_DR EQU 90h ; 存在的只讀數(shù)據(jù)段類型值
DA_DRW EQU 92h ; 存在的可讀寫數(shù)據(jù)段屬性值
DA_DRWA EQU 93h ; 存在的已訪問可讀寫數(shù)據(jù)段類型值
DA_C EQU 98h ; 存在的只執(zhí)行代碼段屬性值
DA_CR EQU 9Ah ; 存在的可執(zhí)行可讀代碼段屬性值
DA_CCO EQU 9Ch ; 存在的只執(zhí)行一致代碼段屬性值
DA_CCOR EQU 9Eh ; 存在的可執(zhí)行可讀一致代碼段屬性值
;----------------------------------------------------------------------------
; 系統(tǒng)段描述符類型值說明
;----------------------------------------------------------------------------
DA_LDT EQU 82h ; 局部描述符表段類型值
DA_TaskGate EQU 85h ; 任務(wù)門類型值
DA_386TSS EQU 89h ; 可用 386 任務(wù)狀態(tài)段類型值
DA_386CGate EQU 8Ch ; 386 調(diào)用門類型值
DA_386IGate EQU 8Eh ; 386 中斷門類型值
DA_386TGate EQU 8Fh ; 386 陷阱門類型值
;----------------------------------------------------------------------------
; 選擇子圖示:
; ┏━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┓
; ┃ 15 ┃ 14 ┃ 13 ┃ 12 ┃ 11 ┃ 10 ┃ 9 ┃ 8 ┃ 7 ┃ 6 ┃ 5 ┃ 4 ┃ 3 ┃ 2 ┃ 1 ┃ 0 ┃
; ┣━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━╋━━━━╋━━━━┻━━━━┫
; ┃ 描述符索引 ┃ TI ┃ RPL ┃
; ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━┻━━━━━━━━━┛
;
; RPL(Requested Privilege Level): 請求特權(quán)級缅疟,用于特權(quán)檢查。
;
; TI(Table Indicator): 引用描述符表指示位
; TI=0 指示從全局描述符表GDT中讀取描述符遍愿;
; TI=1 指示從局部描述符表LDT中讀取描述符存淫。
;
;----------------------------------------------------------------------------
; 選擇子類型值說明
; 其中:SA_ : Selector Attribute
SA_RPL0 EQU 0 ; ┓
SA_RPL1 EQU 1 ; ┣ RPL
SA_RPL2 EQU 2 ; ┃
SA_RPL3 EQU 3 ; ┛
SA_TIG EQU 0 ; ┓TI
SA_TIL EQU 4 ; ┛
;----------------------------------------------------------------------------
; 宏 ------------------------------------------------------------------------------------------------------
;
; 描述符
; usage: Descriptor Base, Limit, Attr
; Base: dd
; Limit: dd (low 20 bits available)
; Attr: dw (lower 4 bits of higher byte are always 0)
%macro Descriptor 3
dw %2 & 0FFFFh ; 段界限(2 字節(jié))
dw %1 & 0FFFFh ; 段基址1(2 字節(jié))
db (%1 >> 16) & 0FFh ; 段基址 2(1 字節(jié))
dw ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh) ; 屬性 1 + 段界限 2 + 屬性 2(2 字節(jié))
db (%1 >> 24) & 0FFh ; 段基址 3(1 字節(jié))
%endmacro ; 共 8 字節(jié)
;
; 門
; usage: Gate Selector, Offset, DCount, Attr
; Selector: dw
; Offset: dd
; DCount: db
; Attr: db
%macro Gate 4
dw (%2 & 0FFFFh) ; 偏移 1 (2 字節(jié))
dw %1 ; 選擇子(2 字節(jié))
dw (%3 & 1Fh) | ((%4 << 8) & 0FF00h) ; 屬性(2 字節(jié))
dw ((%2 >> 16) & 0FFFFh) ; 偏移 2(2 字節(jié))
%endmacro ; 共 8 字節(jié)
; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
; ===========================================================
; pmtest1.asm
; 編譯方法:nasm pmtest1.asm -o pmtest1.bin
; ==========================================================
%include "pm.inc" ;定義一些常量,宏沼填,以及一些說明
org 0100h
jmp LABEL_BEGIN
[SECTION .gdt]
; GDT
;段基址桅咆,段界限,屬性
LABEL_GDT: Descriptor 0, 0, 0 ;空描述符
LABEL_DESC_NORMAL: Descriptor 0, 0ffffh, DA_DRW ;normal 描述符
LABEL_DESC_CODE32: Descriptor 0, SegCode32Len - 1, DA_C + DA_32 ;非一致代碼段
LABEL_DESC_CODE16: Descriptor 0, 0ffffh, DA_C; 非一致代碼段 16
LABEL_DESC_DATA: Descriptor 0, DataLen-1, DA_DRW ;data
LABEL_DESC_STACK: Descriptor 0, TopOfStack, DA_DRWA+DA_32 ;Stack 32位
LABEL_DESC_TEST: Descriptor 0500000h, 0ffffh, DA_DRW
LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW ;顯存首地址
; GDT 結(jié)束
GdtLen equ $ - LABEL_GDT ;GDT 的長度
GdtPtr dw GdtLen - 1 ;GDT界限
dd 0 ; GDT基地址
;GDT選擇子
SelectorNormal equ LABEL_DESC_NORMAL - LABEL_GDT
SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT
SelectorCode16 equ LABEL_DESC_CODE16 - LABEL_GDT
SelectorData equ LABEL_DESC_DATA - LABEL_GDT
SelectorStack equ LABEL_DESC_STACK - LABEL_GDT
SelectorTest equ LABEL_DESC_TEST - LABEL_GDT
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT
;END of [SECTION .gdt]
[SECTION .data1] ;數(shù)據(jù)段
ALIGN 32
[BITS 32]
LABEL_DATA:
SPValueInRealMode dw 0
;字符串
PMMessage: db "In.Protect.Mode.now. ^-^", 0 ;在保護(hù)模式中顯示
OffsetPMMessage equ PMMessage - $$
strTest: db "ABCDEFGGIJKLMNOPQRSTUVWXYZ", 0
OffsetStrTest equ strTest - $$
DataLen equ $ - LABEL_DATA
; END of [Section .data1]
;全局堆棧段
[SECTION .gs]
ALIGN 32
[BITS 32]
LABEL_STACK:
times 512 db 0
TopOfStack equ $ - LABEL_STACK - 1
;end of [SECTION .gs]
[SECTION .s16]
[BITS 16]
LABEL_BEGIN:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0100h ;實(shí)模式下所用內(nèi)存空間為64K(0100h)坞笙,故指定最高地址為棧頂
mov [LABEL_GO_BACK_TO_REAL + 3], ax
mov [SPValueInRealMode], sp
;;初始化15位段描述符
mov ax, cs
movzx eax, ax
shl eax, 4
add eax, LABEL_SEG_CODE16
mov word [LABEL_DESC_CODE16 + 2], ax
shr eax, 16
mov byte [LABEL_DESC_CODE16 + 4], al
mov byte [LABEL_DESC_CODE16 + 7], ah
;;初始化32位代碼段描述符
xor eax, eax
mov ax, cs
shl eax, 4 ;此時處于實(shí)模式運(yùn)行 其段基址與偏移的計(jì)算方式位 cs<<4 + offset
add eax, LABEL_SEG_CODE32
mov word [LABEL_DESC_CODE32 + 2], ax
shr eax, 16
mov byte [LABEL_DESC_CODE32 + 4], al
mov byte [LABEL_DESC_CODE32 + 7], ah
;;初始化數(shù)據(jù)段描述符
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_DATA
mov word [LABEL_DESC_DATA + 2], ax
shr eax, 16
mov byte [LABEL_DESC_DATA + 4], al
mov byte [LABEL_DESC_DATA + 7], ah
;;初始化堆棧描述符
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_STACK
mov word [LABEL_DESC_STACK + 2], ax
shr eax, 16
mov byte [LABEL_DESC_STACK + 4], al
mov byte [LABEL_DESC_STACK + 7], ah
;;為加載GDTR做準(zhǔn)備
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_GDT ;eax <-gdt基地址
mov dword [GdtPtr + 2], eax ; 將地址賦給GdtPtr高2個字節(jié)
;;加載GDTR
lgdt [GdtPtr]
;;關(guān)閉中斷
cli
;;打開地址線 A20
in al, 92h
or al, 00000010b
out 92h, al
;;準(zhǔn)備切換到保護(hù)模式
mov eax, cr0
or eax, 1
mov cr0, eax
;;真正進(jìn)入保護(hù)模式
jmp dword SelectorCode32:0 ;;執(zhí)行此句會將Selectorcode32裝入cs岩饼,
;;并跳轉(zhuǎn)到Code32Selector:0處,
LABEL_REAL_ENTRY:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, [SPValueInRealMode]
in al, 92h
or al, 11111101b
out 92h, al
sti
mov ax, 4c00h
int 21h ;;回到dos
;;END of [SECTION .s16]
[SECTION .s32] ;;進(jìn)入32位代碼 由實(shí)模式跳入
[BITS 32]
LABEL_SEG_CODE32:
mov ax, SelectorVideo
mov gs, ax ;視頻段選擇子
mov ax, SelectorTest
mov es, ax
mov ax, SelectorData
mov ds, ax
mov ax, SelectorStack
mov ss, ax
mov esp, TopOfStack
;下面顯示一個字符
mov ah, 0ch ;; 0000 黑底薛夜, 1100:紅字
xor esi, esi
xor edi, edi
mov esi, OffsetPMMessage ;;源數(shù)據(jù)偏移
mov edi (80*10 + 0) *2
cld ;;//清除方向標(biāo)識籍茧,使其為 0
.1:
lodsb ;;//將ds中si所指向的內(nèi)容按字節(jié)加載到al中,由于方向標(biāo)志為0梯澜,故si自動+1
test al, al
jz .2
mov [gs:edi], ax
add edi, 2
jmp .1
.2: ;顯示完畢
call DispReturn
call TestRead
call TestWrite
call TestRead
;;到此停止寞冯,再次跳轉(zhuǎn)回 實(shí)模式
jmp SelectCode16:0
TestRead:
xor esi, esi
mov ecx, 8
.loop:
mov al, [es:esi]
call DispAL
inc esi
loop .loop
call DispReturn
ret
;;Testread 結(jié)束
TestWrite:
push esi
push edi
xor esi, esi
xor edi, edi
mov esi, OffsetStrTest ;;源數(shù)據(jù)
cld
.1:
lodsb
test al, al
jz .2
mov [es:edi], al
inc edi
jmp .1
.2:
pop edi
pop esi
ret
;;Testwrite 結(jié)束
;;
;;顯示AL中的數(shù)字
;;默認(rèn)地:
;;數(shù)字已經(jīng)存在AL中
;;edi始終指向要顯示的下一個字符的位置
;;被改變的寄存器 ax, edi
DispAL:
push edx
push ecx
mov ah, 0ch
mov dl, al
shr al, 4
mov ecx, 2
.begin:
and al, 01111b
cmp al, 9
ja .1
add al, '0'
jmp .2
.1:
sub al, 0Ah
add al, 'A'
.2:
mov [gs:edi], ax
add edi, 2
mov al, dl
loop .begin
add edi, 2
pop edx
pop ecx
ret
;;DispAL 結(jié)束
DispReturn:
push eax
push ebx
mov eax, edi
mov bl, 160
div bl
and eax, 0ffh
inc eax
mov bl, 160
mul bl
mov edi, eax
pop ebx
pop eax
ret
;;Dispreturn 結(jié)束
;mov edi, (80 * 11 + 79) * 2
;mov ah, 0ch
;mov al, 'D'
;mov [gs:edi], ax
;;end
jmp $
SegCode32Len equ $ - LABEL_SEG_CODE32
;;end of [SECTION .s32]
;;16位代碼段,由32位跳入晚伙,從而進(jìn)入實(shí)模式
[SECTION .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
Code16Len equ $-LABEL_SEG_CODE16
保護(hù)模式與實(shí)模式跳轉(zhuǎn)的步驟:
- BIOS完成后吮龄,程序到0100h處執(zhí)行,接著跳轉(zhuǎn)到16位代碼段進(jìn)行執(zhí)行(注意此時 cs為實(shí)模式下16位代碼段基址)咆疗,在16位dos實(shí)模式下堆棧初始化位置位0100h漓帚。接下來進(jìn)行數(shù)據(jù)段,代碼段民傻,堆棧段胰默,段描述符的初始化工作场斑。
- 此處為后面從保護(hù)模式跳轉(zhuǎn)回實(shí)模式的一步關(guān)鍵準(zhǔn)備工作:
mov [LABEL_GO_BACK_TO_REAL + 3], ax ; mov [SPValueInRealMode], sp
此處將LABEL_GO_BACK_TO_REAL 標(biāo)簽后第3字節(jié)開始,填充位實(shí)模式的代碼段基址牵署。并保存堆棧地址漏隐。 - 打開地址線 A20,設(shè)置保護(hù)模式開啟位
- 跳轉(zhuǎn)進(jìn)入保護(hù)模式奴迅,
jmp dword SelectorCode32:0
青责。 - 實(shí)模式完成顯示任務(wù)
- 執(zhí)行'jmp SelectCode:0'跳轉(zhuǎn)到16位的保護(hù)模式到實(shí)模式過渡代碼段(.s16code)執(zhí)行。
- 此處注意
mov ax, SelectorNormal
的作用為:因?yàn)楸Wo(hù)模式下GDT的高速緩沖寄存器中內(nèi)容必須進(jìn)行清理取具,這里利用SelectorNormal將GDT的高速緩沖寄存器中內(nèi)容替換為實(shí)模式下中的內(nèi)容脖隶,注意:實(shí)模式下所有段的fffffh--00000h,且讀寫屬性應(yīng)該為可讀寫暇检。
8.由于jmp的跳轉(zhuǎn)地址已經(jīng)在步驟2中改寫為實(shí)模式下代碼段的基址产阱。
代碼中有幾點(diǎn)需要注意的地方:
org 0100h
org不是操作符而是編譯時的標(biāo)記,最終的二進(jìn)制代碼中并不存在此操作符块仆。該標(biāo)記粗略來說有兩個作用:
- 指定程序的加載到內(nèi)存的實(shí)際開始地址
- 指明對于程序中的常量要進(jìn)行相對編址(例如:若加org构蹬,常量字符串位于 org + offset;若不加 org悔据,則常量字符串的編址為 0 + offset)
初始化GDT描述符基址的方法
xor eax, eax ;清除eax
mov ax, ds ;此時 ds 為實(shí)模式下代碼段基址
shl eax, 4 ;此時處于實(shí)模式運(yùn)行 其段基址與偏移的計(jì)算方式位 cs<<4 + offset
add eax, LABEL_DATA ;此處為offset
mov word [LABEL_DESC_DATA + 2], ax ;將基址的0-15位賦予GDT的2庄敛,3字節(jié)
shr eax, 16 ;將基址右移16位,ax變?yōu)榛返?科汗,4字節(jié)
mov byte [LABEL_DESC_DATA + 4], al
mov byte [LABEL_DESC_DATA + 7], ah