保護(hù)模式與實(shí)模式切換以及GDT(全局描述符表)

; 描述符圖示

; 圖示一
;
;  ------ ┏━━━┳━━━━━┓高地址
;         ┃ 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)的步驟:

  1. BIOS完成后吮龄,程序到0100h處執(zhí)行,接著跳轉(zhuǎn)到16位代碼段進(jìn)行執(zhí)行(注意此時 cs為實(shí)模式下16位代碼段基址)咆疗,在16位dos實(shí)模式下堆棧初始化位置位0100h漓帚。接下來進(jìn)行數(shù)據(jù)段,代碼段民傻,堆棧段胰默,段描述符的初始化工作场斑。
  2. 此處為后面從保護(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í)模式的代碼段基址牵署。并保存堆棧地址漏隐。
  3. 打開地址線 A20,設(shè)置保護(hù)模式開啟位
  4. 跳轉(zhuǎn)進(jìn)入保護(hù)模式奴迅,jmp dword SelectorCode32:0青责。
  5. 實(shí)模式完成顯示任務(wù)
  6. 執(zhí)行'jmp SelectCode:0'跳轉(zhuǎn)到16位的保護(hù)模式到實(shí)模式過渡代碼段(.s16code)執(zhí)行。
  7. 此處注意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 
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末藻烤,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子头滔,更是在濱河造成了極大的恐慌怖亭,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拙毫,死亡現(xiàn)場離奇詭異依许,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)缀蹄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來膘婶,“玉大人缺前,你說我怎么就攤上這事⌒螅” “怎么了衅码?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長脊岳。 經(jīng)常有香客問我逝段,道長垛玻,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任奶躯,我火速辦了婚禮帚桩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘嘹黔。我一直安慰自己账嚎,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布儡蔓。 她就那樣靜靜地躺著郭蕉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪喂江。 梳的紋絲不亂的頭發(fā)上召锈,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天,我揣著相機(jī)與錄音获询,去河邊找鬼涨岁。 笑死,一個胖子當(dāng)著我的面吹牛筐付,可吹牛的內(nèi)容都是我干的卵惦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼瓦戚,長吁一口氣:“原來是場噩夢啊……” “哼沮尿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起较解,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤畜疾,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后印衔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啡捶,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年奸焙,在試婚紗的時候發(fā)現(xiàn)自己被綠了瞎暑。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡与帆,死狀恐怖了赌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情玄糟,我是刑警寧澤勿她,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站阵翎,受9級特大地震影響逢并,放射性物質(zhì)發(fā)生泄漏之剧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一砍聊、第九天 我趴在偏房一處隱蔽的房頂上張望背稼。 院中可真熱鬧,春花似錦辩恼、人聲如沸雇庙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽疆前。三九已至,卻和暖如春聘萨,著一層夾襖步出監(jiān)牢的瞬間竹椒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人硼身。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像赊窥,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子狸页,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 8086匯編 本筆記是筆者觀看小甲魚老師(魚C論壇)《零基礎(chǔ)入門學(xué)習(xí)匯編語言》系列視頻的筆記坝初,在此感謝他和像他一樣...
    Gibbs基閱讀 37,198評論 8 114
  • 可以將一個單獨(dú)的任務(wù)所用到的所有東西都封裝在一個LDT中浸剩。 step1.增加一個32位的代碼段:LABEL_COD...
    王偵閱讀 1,138評論 0 0
  • 這個程序的核心目的是:試驗(yàn)大地址的讀寫,在保護(hù)模式下面尋址空間可達(dá)4GB鳄袍,實(shí)模式下只能尋址1MB乒省。(why:為什么...
    王偵閱讀 816評論 0 0
  • 核心目的:實(shí)現(xiàn)由實(shí)模式到保護(hù)模式的轉(zhuǎn)換 核心步驟: 1)程序定義了GDT數(shù)據(jù)結(jié)構(gòu) 2)16位代碼進(jìn)行了一些...
    王偵閱讀 1,125評論 0 0
  • 王爽匯編全書知識點(diǎn)大綱 第一章 基礎(chǔ)知識 機(jī)器語言 匯編語言的產(chǎn)生 匯編語言的組成 存儲器 cpu對存儲器的讀寫 ...
    2c3ba901516f閱讀 2,417評論 0 1