EA20 macro; // Open the A20 address line
Push AX
IN Al, 92H
OR Al, 00000010B
OUT 92H, Al
POP AX
ENDM
; ------------------------------------------------- ---------------------------
Close the A20 address line
; ------------------------------------------------- ---------------------------
DA20 Macro
Push AX
IN Al, 92H
And Al, 11111101B
OUT 92H, Al
POP AX
ENDM
; ------------------------------------------------- ---------------------------
Jump macro selector, offsetv; // jump macro
DB 0eah
DW offsetv
DW selector
ENDM
; ---------------------
Call16 Macro Selector, Offsetv
DB 9ah
DW offsetv
DW selector
ENDM
; ----------------------
Descriptor struc; // Descriptor structure
Limitl DW 0
Basel DW 0
Basem DB 0
Attributes dw 0
Baseh DB 0
Descriptor ENDS
; ------------------------------------------------- ----------------------------
Gate struch
Offsetl dw 0
Selector DW 0
DCOUNT DB 0
GTYPE DB 0
Offseth dw 0
Gate Ends
; ---------------------
PDESC STRUC; // Pseudo Description
Limit DW 0
Base DD 0
PDESC ENDS
;
ATDW = 92H
ATCE = 98h
Atcer = 9ah
ATLDT = 82H; local descriptor table segment type value
TIL = 04h
AT386TSS = 89h
AT386CGATE = 8CH; 386 call door type value
DPL1 = 20h
DPL2 = 40h
DPL3 = 60h
RPL1 = 01H
RPL2 = 02h
RPL3 = 03h ;;;;;;;;;;;;;
.386P
GDTSEG segment us16
GDT Label Byte
Dummy descriptor <>
;
Code Descriptor <0FFFFH,, ATCE,>
Code_sel = Code-GDT
; Descriptor of code segment codekseg
Codek Descriptor <0FFFFH,, ATCE,>
Codek_sel = Codek-GDT
General descriptor
Normal Descriptor <0FFFFH,, ATDW,>
NORMAL_SEL = Normal-GDT
;
TSS Descriptor <0FFFFH,, AT386TSS,>
TSS_SEL = TSS-GDT
; Partial descriptor
LDTable Descriptor <0FFFFH,, ATLDT,> LDT_SEL = LDTABLE-GDT
GDTLEN = $ - GDT
VGDTR PDESC
GDTSEG Ends
; ------------------------------------------------- -----------------
Partial description table
LDTSEG segment use6
LDT Label Byte
Data segment LDTSEG descriptor
Data Descriptor <0FFFFH,, ATDW,>
Data_sel = (Data-LDT) TIL
; Descriptor of the code segment vcode
Vcode Descriptor <0FFFFH,, ATCE DPL3,>>
vcode_sel = (vcode-ldt) TIL RPL3
; To display the data
VData Descriptor <0FFFFH,, ATDW DPL3,>
VDATA_SEL = (VDATA-LDT) TIL RPL3
; Data to display 2
VData1 Descriptor <0FFFFH,, ATDW DPL3,>
VDATA1_SEL = (VDATA1-LDT) TIL RPL3
;
Vbuf descriptor <0fffh, 8000H, 0BH, ATDW DPL3,>
VBUF_SEL = (VBUF-LDT) TIL RPL3
;
Stack0t Descriptor <0FFFFH,, ATDW,>
STACK0T_SEL = (STACK0T-LDT) TIL
;
Stack3t Descriptor <0FFFFH,, ATDW DPL3,>
Stack3t_sel = (stack3t-ldt) TIL RPL3
TOVBUF GATE
TOVBUF_SEL = (Tovbuf-LDT) TIL
LDTSEG ENDS
; ------------------------------------------------- ---
TSSSEG Segment USE16
DD 0; Back
DW stack0len, 0; 0-level stack pointer
DW stack0t_sel, 0; initialization
DW 0, 0; 1 stack pointer
DW 0,0; initialization
DD?; Level 2 stack pointer
DW?, 0; not initialized
DD 0; CR3
DD?; EIP
DD?; EFLAGS
DD?; EAX
DD?; ECX
DD?; EDX
DD?; EBX
DD?; ESP
DD?; EBP
DD?; ESI
DD?; EDI
DW?, 0; ES
DW?, 0; CS
DW?, 0; ss
DW?, 0; DS
DW?, 0; FS
DW?, 0; GS
DW LDT_SEL, 0; LDT
DW 0
DW $ 2; point to I / O license bitmap DB 0FFH; I / O license bitmap end flag
TSSSEG Ends
;
Stack0 Segment
STACK0LEN = 512
DB Stack0len DUP (0)
Stack0 Ends
;
Stack3 segment
STACK3LEN = 512
DB Stack3len DUP (0)
Stack3 Ends
; ------------------------------------------------- ---
Vdseg segment use6
YANG DB 'How Are you', 0
VDSEG Ends
; ------------------------------------------------- ----
vdseg1 segment us16
Hello DB 'Hello', 0
Hellolen = $ - Hello
VDSEG1 ENDS
; ------------------------------------------------- ----
vcseg segment us16
Assume cs: vcseg
vStart: MOV AX, VDATA_SEL
MOV DS, AX
MOV AX, VBUF_SEL
Mov ES, AX
Lea Si, YANG
XOR BX, BX
MOV CX, 11
Again: MOV Al, [Si]
MOV AH, 87H
MOV ES: [BX], AX
Add bx, 2
Inc Si
Loop again
Hello
MOV AX, VDATA1_SEL
MOV DS, AX
Lea Si, Hello
Mov CX, Hellolen
Again1: MOV Al, [Si]
MOV AH, 0F4H
MOV ES: [BX], AX
Add bx, 2
Inc Si
LOOP AGAIN1
Call16 Tovbuf_sel, 0
Vcseg Ends
; ---------------------------------
Codekseg segment use6; this code implements the conversion from level 0 to level 3. Very critical! ! ! !
Assume CS: Codekseg;
Startk: MOV AX, TSS_SEL
LTR AX
MOV AX, LDT_SEL
LLDT AX
MOV AX, Stack0T_SEL;
MOV SS, AX;
Mov ESP, Stack0len; Creating a 0-level stack
Push Word PTR Stack3t_sel; a pointer to the 3-level stack.
Push Word PTR Stack3len
Push Word Ptr vcode_sel; pressing the entrance address
Push offset vStart
RETF; implementation of transition from level 0 to level 3
Tojump: jump
CodekSeg Ends
; ??????????????????????????????????????????????????????????????????????????????? ;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;
CSEG segment use6
Assume CS: CSEG, DS: GDTSEGSTART: MOV AX, GDTSEG
MOV DS, AX
MOV BX, 16
Mul bx
Add Ax, Offset GDT
ADC DX, 0
Mov Word Ptr vgdtr.base, AX
Mov Word Ptr Vgdtr.Base 2, DX
;
MOV AX, CSEG
Mul bx
Mov Word Ptr Code.Basel, AX
MOV BYTE PTR Code.basem, DL
Mov Byte Ptr Code.baseh, DH
;
Mov AX, Codekseg
Mul bx
Mov Word PTR Codek.Basel, AX
Mov Byte Ptr Codek.basem, DL
Mov Byte Ptr Codek.Baseh, DH
;
MOV AX, LDTSEG
Mul bx
Mov Word Ptr Ldtable.Basel, AX
MOV BYTE PTR LDTABLE.BASEM, DL
Mov Byte Ptr Ldtable.Baseh, DH
;
Mov AX, TSSSEG
Mul bx
Mov Word PTR TSS.BASEL, AX
Mov Byte PTR TSS.BASEM, DL
Mov Byte Ptr TSS.Baseh, DH
;
Push DS
Assume DS: ldtseg
MOV AX, LDTSEG
MOV DS, AX
MOV AX, VDSEG
Mul bx
Mov Word Ptr vdata.Basel, AX
MOV BYTE PTR VDATA.BASEM, DL
Mov Byte Ptr vdata.baseh, DH
;
MOV AX, VDSEG1
Mul bx
Mov Word Ptr vdata1.basel, AX
MOV BYTE PTR VDATA1.BASEM, DL
Mov Byte Ptr vdata1.baseh, DH
;
MOV AX, VCSEG
Mul bx
MOV Word Ptr vcode.basel, AX ;;;;;;;;;;;;;;;;
MOV BYTE PTR VCODE.BASEM, DL ;;;;;;;;;;;;;;;;
MOV BYTE PTR Vcode.baseh, DH ;;;;;;;;;;;;;;;;
;
POP DS
Assume DS: GDTSEG
LGDT QWORD PTR VGDTR
CLI
MOV Eax, Cr0
OR AX, 1
MOV CR0, EAX
Jump
Toreal: Mov AX, Normal_SEL
MOV DS, AX
MOV Eax, Cr0
And Eax, 0FFFFFFEH
MOV CR0, EAX
Jump
REAL: DA20
STI
MOV AH, 4CH
Int 21h
CSEG Ends
End Start