实践GDT和LDT

%include "pm.inc"

; 实践LDT
ORG    0100h

JMP REALMODE_START
; ########################################################################
; Define GDT
[SECTION .GDT]
GDT_BEGIN:
LABEL_DESC_NULL        :Descriptor    0,    0,                    0
LABEL_DESC_NORMAL    :Descriptor    0,    0FFFFh,             DA_DRW
LABEL_DESC_CODE32    :Descriptor    0,    SegCode32Len - 1,    DA_C + DA_32
LABEL_DESC_CODE16    :Descriptor    0,    SegCode16Len - 1,    DA_C
LABEL_DESC_DATA        :Descriptor    0,    SegDataLen - 1,        DA_DRW
LABEL_DESC_STACK    :Descriptor    0,    TopOfStack,            DA_DRWA + DA_32
LABEL_DESC_LDT        :Descriptor    0,    LDTLen - 1,            DA_LDT
LABEL_DESC_VIDEO    :Descriptor    0B8000h,    0FFFFh,        DA_DRW

;GDTR
GDTLen    EQU    $ - $$
GDTPtr    DW    GDTLen - 1
        DD    0

;Define GDT Selectors
SelNormal    EQU    LABEL_DESC_NORMAL    - $$
SelCode32    EQU    LABEL_DESC_CODE32    - $$
SelCode16    EQU    LABEL_DESC_CODE16    - $$
SelData        EQU    LABEL_DESC_DATA        - $$
SelStack    EQU    LABEL_DESC_STACK    - $$
SelLDT        EQU    LABEL_DESC_LDT        - $$
SelVideo    EQU    LABEL_DESC_VIDEO    - $$

; THIS IS THE END OF DEFINATION OF GDT SEGMENT
; ########################################################################

; Define LDT
[SECTION .LDT]
ALIGN 32
LDT_BEGIN:
LABEL_LDT_DESC_CODE32    :Descriptor    0,    LDTCodeLen - 1, DA_C + DA_32

LDTLen    EQU    $ - $$

SelLDTCode32    EQU    LABEL_LDT_DESC_CODE32 - $$ + SA_TIL

; THIS IS THE END OF DEFINATION OF LDT SEGMENT
; ########################################################################

; Define 32 bits stack segment
[SECTION .STACK32]
ALIGN 32
[BITS 32]
STACK_BEGIN:
    times 512    DB 0
TopOfStack    EQU $ - $$ - 1

; THIS IS THE END OF DEFINATION OF 32 BITS STACK SEGMENT
; ########################################################################

; Define 32 bits data segment
[SECTION .DATA32]
ALIGN 32
[BITS 32]
DATA_BEGIN:

SPBakup                DW    0 ;实模式下的SP值(备份)
PMMessage            DB    "In Protected Mode NOW!", 0
OffsetPMMessage        EQU    PMMessage - $$
TestString            DB    "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0
OffsetTestString    EQU    TestString - $$

SegDataLen        EQU    $ - $$
; THIS IS THE END OF DEFINATION OF 32 BITS DATA SEGMENT
; ########################################################################

; 16 bits real mode code segment       
[SECTION .REALMODE]
[BITS 16]
REALMODE_START:
    MOV    AX,CS
    MOV DS,AX
    MOV ES,AX
    MOV SS,AX
    MOV SP,100h
    ;###############DEBUG CODE########################
JMPSEG   EQU   40H     
MOV      AX,JMPSEG
MOV    DS,AX              
MOV       AX,[DS:0]           
PUSH       AX              
MOV      BYTE [DS:0],0CBH     
PUSH      CS
PUSH      BACK           
DB      0EAH              
DW      0
DW      JMPSEG
BACK:                 
POP      AX
MOV      [DS:0],AX           
MOV        AX,CS
MOV        DS,AX

    ; Set real mode segment address and sp value
    MOV    [BACK_TO_REAL + 3], AX
    MOV    [SPBakup], SP
    ; Initialize 16 bits code segment descriptor
    ; This segment is used for jump back to real mode
    XOR    EAX,EAX
    MOV    AX,CS
    SHL    EAX,4
    ADD    EAX,READY_BACK_TO_REAL
    MOV WORD [LABEL_DESC_CODE16 + 2],AX
    SHR EAX,16
    MOV BYTE [LABEL_DESC_CODE16 + 4],AL
    MOV BYTE [LABEL_DESC_CODE16 + 7],AH
    ; Initialize 32 bits code segment descriptor
    XOR    EAX,EAX
    MOV    AX,CS
    SHL    EAX,4
    ADD    EAX,PROTECTMODE_START
    MOV WORD [LABEL_DESC_CODE32 + 2],AX
    SHR EAX,16
    MOV BYTE [LABEL_DESC_CODE32 + 4],AL
    MOV BYTE [LABEL_DESC_CODE32 + 7],AH
    ; Initialize 32 bits data segment descriptor
    XOR    EAX,EAX
    MOV    AX,CS
    SHL    EAX,4
    ADD    EAX,DATA_BEGIN
    MOV WORD [LABEL_DESC_DATA + 2],AX
    SHR EAX,16
    MOV BYTE [LABEL_DESC_DATA + 4],AL
    MOV BYTE [LABEL_DESC_DATA + 7],AH
    ; Initialize 32 bits stack segment descriptor
    XOR    EAX,EAX
    MOV    AX,CS
    SHL    EAX,4
    ADD    EAX,STACK_BEGIN
    MOV WORD [LABEL_DESC_STACK + 2],AX
    SHR EAX,16
    MOV BYTE [LABEL_DESC_STACK + 4],AL
    MOV BYTE [LABEL_DESC_STACK + 7],AH

    ; Initialize LDT segment descriptor in GDT
    XOR    EAX,EAX
    MOV    AX,CS
    SHL    EAX,4
    ADD    EAX,LDT_BEGIN
    MOV WORD [LABEL_DESC_LDT + 2],AX
    SHR EAX,16
    MOV BYTE [LABEL_DESC_LDT + 4],AL
    MOV BYTE [LABEL_DESC_LDT + 7],AH
    ; Initialize the segment descriptor in the LDT
    XOR    EAX,EAX
    MOV    AX,CS
    SHL    EAX,4
    ADD    EAX,LDTCODE32_START
    MOV WORD [LABEL_LDT_DESC_CODE32 + 2],AX
    SHR EAX,16
    MOV BYTE [LABEL_LDT_DESC_CODE32 + 4],AL
    MOV BYTE [LABEL_LDT_DESC_CODE32 + 7],AH
    ; Ready for load GDT into GDTR
    XOR    EAX,EAX
    mov    AX,CS
    SHL    EAX,4
    ADD    EAX,GDT_BEGIN
    MOV    DWORD [GDTPtr + 2],EAX
    LGDT    [GDTPtr]
    ; Disable Interupt
    CLI
    ; Enable A20
    IN    AL, 92h
    OR    AL, 00000010b
    OUT    92h,AL
    ; Enable protect mode
    MOV    EAX,CR0
    OR    EAX,1
    MOV    CR0,EAX
    ; JMP TO PROTECT MODE 32 BITS CODE SEGMENT!!!
    JMP DWORD SelCode32:0
    ; PROTECT MODE BACK TO REAL MODE LANDING ZONE
LANDING_ZONE:
    MOV    AX,CS
    MOV    DS,AX
    MOV    ES,AX
    MOV    SS,AX
    MOV    SP,[SPBakup]
    ; Disable A20
    IN    AL,92h
    AND    AL,11111101b
    OUT    92h,AL
    ; Set interupt
    STI
    ; EXIT
    MOV    AX,4C00h
    INT    21h
; THIS IS THE END OF 16 BITS REAL MODE SEGMENT
; ########################################################################   

; 32 bits segment in protect mode
[SECTION .CODE32]
ALIGN 32
[BITS 32]
PROTECTMODE_START:
    MOV    AX,SelData
    MOV    DS,AX
    MOV AX,SelVideo
    MOV    GS,AX
    MOV    AX,SelStack
    MOV    SS,AX
    MOV    ESP,TopOfStack
    ;SHOW WE ARE ALREADY IN PROTECT MODE!
    ; Print string by write video memory directly
    MOV    AH,0Ch
    XOR    ESI,ESI
    XOR    EDI,EDI
    MOV    ESI, OffsetPMMessage
    MOV    EDI, (80 * 10 + 0) * 2
    CLD
.1:
    LODSB
    TEST    AL,AL
    JZ    .2
    MOV    [GS:EDI],AX
    ADD    EDI,2
    JMP    .1
.2:
    call    DisplayReturn
    MOV    AX, SelLDT
    LLDT    AX
    ; Jump into LDT 32 bits code segment
    JMP    SelLDTCode32:0
DisplayReturn:
    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

SegCode32Len    EQU $ - $$

; THIS IS THE END OF 32 BITS PROTECT MODE SEGMENT
; ########################################################################

; LDT 32 BITS CODE SEGMENT
[SECTION .LDTCODE32]
ALIGN 32
[BITS 32]
LDTCODE32_START:
    MOV    AX, SelVideo
    MOV    GS, AX                    ; 视频段选择子(目的)

    MOV    EDI, (80 * 12 + 0) * 2    ; 屏幕第 10 行, 第 0 列。
    MOV    AH, 0Dh                    ; 0000: 黑底    1100: 红字
    MOV    AL, 'L'
    MOV    [GS:EDI], AX
    ; Ready back to real mode
    JMP SelCode16:0
LDTCodeLen    EQU $ - $$

; THIS IS THE END OF 32 BITS PROTECT MODE LDT CODE SEGMENT
; ########################################################################

; PROTECT MODE 16 BITS CODE SEGMENT
; USED FOR BACK TO REAL MODE

[SECTION .CODE16]
ALIGN 16
[BITS 32]
READY_BACK_TO_REAL:
    MOV    AX,SelNormal
    MOV DS,AX
    MOV ES,AX
    MOV FS,AX
    MOV GS,AX
    MOV SS,AX
    MOV EAX, CR0
    AND EAX, 11111110b
    MOV CR0, EAX
BACK_TO_REAL:
    JMP    0:LANDING_ZONE

SegCode16Len    EQU $ - $$

; THIS IS THE END OF 16 BITS PROTECT MODE CODE SEGMENT
; ########################################################################

posted @ 2010-03-01 00:42  robinh00d  阅读(582)  评论(0编辑  收藏  举报