测试环境:Win98下的DOS7,用MASM6.11编译。
.386P
DESC STRUC
LIMIT DW 0
BASEL DW 0
BASEM DB 0
ATTR DW 0
BASEH DB 0
DESC ENDS
GDTR STRUC
LIMIT DW 0
BASE DD 0
GDTR ENDS
STACK SEGMENT USE16
DB 256 DUP (0)
STACKLEN = $
STACK ENDS
DATA SEGMENT USE16
GDT DESC <>
GDTNULL = 0
GDTCODE DESC <0FFFFH, 0, 0, 98H, 0>
GDTCODESEL = OFFSET GDTCODE - OFFSET GDT
GDTDATA DESC <0FFFFH, 0, 0, 92H, 0>
GDTDATASEL = OFFSET GDTDATA - OFFSET GDT
GDTSTACK DESC <0FFFFH, 0, 0, 92H, 0>
GDTSTACKSEL = OFFSET GDTSTACK - OFFSET GDT
;
GDTCODEA DESC <0FFFFH, 0, 0,4098H, 0>
GDTCODEASEL = OFFSET GDTCODEA - OFFSET GDT
GDTSTACKA DESC <0FFFFH, 0, 0, 92H, 0>
GDTSTACKASEL = OFFSET GDTSTACKA - OFFSET GDT
GDTCODEB DESC <0FFFFH, 0, 0, 40F8H, 0>
GDTCODEBSEL = OFFSET GDTCODEB - OFFSET GDT
GDTSTACKB DESC <0FFFFH, 0, 0, 92H, 0>
GDTSTACKBSEL = OFFSET GDTSTACKB - OFFSET GDT
;
GDTCODE0 DESC <0FFFFH, 0, 0, 4098H, 0>
GDTCODE0SEL = OFFSET GDTCODE0 - OFFSET GDT
GDTSTACK0 DESC <0FFFFH, 0, 0, 92H, 0>
GDTSTACK0SEL = OFFSET GDTSTACK0 - OFFSET GDT
GDTDATA0 DESC <0FFFFH, 0, 0, 92H, 0>
GDTDATA0SEL = OFFSET GDTDATA0 - OFFSET GDT
GDTDATA3 DESC <0FFFFH, 0, 0, 40F2H, 0>
GDTDATA3SEL = OFFSET GDTDATA3 - OFFSET GDT
GDTDISP0 DESC <0FFFFH, 8000H, 0BH, 92H, 0>
GDTDISP0SEL = OFFSET GDTDISP0 - OFFSET GDT
GDTDISP3 DESC <0FFFFH, 8000H, 0BH, 0F2H, 0>
GDTDISP3SEL = OFFSET GDTDISP3 - OFFSET GDT
NEWGDTR GDTR <OFFSET NEWGDTR - OFFSET GDT, 0>
OLDGDTR GDTR <>
DATA ENDS
CODE SEGMENT USE16
ASSUME DS:DATA, CS:CODE, SS:STACK
START:
MOV AX, DATA
MOV DS, AX
CLI
MOV AX, STACK
MOV SS, AX
MOV SP, STACKLEN
STI
MOV AX, DATA
MOV BX, 10H
MUL BX
MOV GDTDATA.BASEL, AX
MOV GDTDATA.BASEM, DL
MOV GDTDATA.BASEH, DH
ADD AX, OFFSET GDT
ADC DX, 0
MOV WORD PTR NEWGDTR.BASE, AX
MOV WORD PTR NEWGDTR.BASE + 2, DX
MOV AX, STACK
MOV BX, 10H
MUL BX
MOV GDTSTACK.BASEL, AX
MOV GDTSTACK.BASEM, DL
MOV GDTSTACK.BASEH, DH
MOV AX, CODE
MOV BX, 10H
MUL BX
MOV GDTCODE.BASEL, AX
MOV GDTCODE.BASEM, DL
MOV GDTCODE.BASEH, DH
MOV AX, DATA0
MOV BX, 10H
MUL BX
MOV GDTDATA0.BASEL, AX
MOV GDTDATA0.BASEM, DL
MOV GDTDATA0.BASEH, DH
MOV AX, STACK0
MOV BX, 10H
MUL BX
MOV GDTSTACK0.BASEL, AX
MOV GDTSTACK0.BASEM, DL
MOV GDTSTACK0.BASEH, DH
MOV AX, CODE0
MOV BX, 10H
MUL BX
MOV GDTCODE0.BASEL, AX
MOV GDTCODE0.BASEM, DL
MOV GDTCODE0.BASEH, DH
MOV AX, DATA3
MOV BX, 10H
MUL BX
MOV GDTDATA3.BASEL, AX
MOV GDTDATA3.BASEM, DL
MOV GDTDATA3.BASEH, DH
CLI
SGDT FWORD PTR OLDGDTR
LGDT FWORD PTR NEWGDTR
MOV EAX, CR0
OR EAX, 1
MOV CR0, EAX
DB 0EAH
DW 0
DW GDTCODE0SEL
RETURN:
MOV EAX, CR0
AND EAX, 0FFFFFFFEH
MOV CR0, EAX
DB 0EAH
DW OFFSET REAL
DW SEG REAL
REAL:
MOV AX, DATA0
MOV ES, AX
MOV AX, STACK0
MOV SS, AX
MOV SP, STACK0LEN
STI
MOV AH, 4CH
INT 21H
CODE ENDS
STACK0 SEGMENT USE32
DB 256 DUP (0)
STACK0LEN = $
STACK0 ENDS
DATA0 SEGMENT USE32
MESS0 DB 'HELLO WORLD!', 0
MESS1 DB 'RETURN TO RING0:)', 0
DATA0 ENDS
CODE0 SEGMENT USE32
ASSUME DS:DATA0,CS:CODE0,SS:STACK0
MOV AX, GDTDATA0SEL
MOV DS, AX
MOV AX, GDTDISP0SEL
MOV ES, AX
MOV AX, GDTSTACK0SEL
MOV SS, AX
MOV ESP, OFFSET STACK0LEN
MOV AX, GDTNULL
MOV FS, AX
MOV GS, AX
MOV ESI, OFFSET MESS0
MOV EDI, 0
CLD
MOV AH, 7
NEXT0:
LODSB
CMP AL, 0
JZ OVER0
STOSW
JMP NEXT0
OVER0:
;BEGIN TO SYSEXIT
XOR EDX, EDX
XOR EAX, EAX
MOV AX, GDTCODEASEL
MOV ECX, 174H
DW 300FH ;WRMSR
MOV ECX, 175H
XOR EDX, EDX
MOV EAX, STACK0LEN
DW 300FH
MOV ECX, 176H
MOV AX, CODE0
MOV BX, 10H
MUL BX
AND EAX, 0FFFFH
SHL EDX, 16
AND EDX, 0FFFF0000H
OR EAX, EDX
XOR EDX, EDX
ADD EAX, OFFSET RETURN0
ADC EDX, 0
DW 300FH
MOV AX, STACK3
MOV BX, 10H
MUL BX
MOV ECX, EDX
SHL ECX, 16
MOV CX, AX
ADD ECX, STACK3LEN ;ESP
MOV AX, CODE3
MOV BX, 10H
MUL BX
SHL EDX,16
MOV DX, AX ;EIP
DW 350FH ;SYSEXIT
RETURN0:
MOV AX, GDTDISP0SEL
MOV ES, AX
MOV AX, GDTDATA0SEL
MOV DS, AX
MOV AH, 7
MOV ESI, OFFSET MESS1
MOV EDI, 80 * 4
CLD
NEXT1:
LODSB
CMP AL, 0
JZ OVER1
STOSW
JMP NEXT1
OVER1:
DB 0EAH
DW OFFSET RETURN
DW 0
DW GDTCODESEL
CODE0 ENDS
STACK3 SEGMENT USE32
DB 256 DUP (0)
STACK3LEN = $
STACK3 ENDS
DATA3 SEGMENT USE32
MESS3 DB 'RING3 ! SEE ME?', 0
DATA3 ENDS
CODE3 SEGMENT USE32
ASSUME DS:DATA3,CS:CODE3, SS:STACK3
MOV AX, GDTDATA3SEL
MOV DS, AX
MOV AX, GDTDISP3SEL
MOV ES, AX
MOV AX, GDTNULL
MOV FS, AX
MOV GS, AX
MOV ESI, OFFSET MESS3
MOV EDI, 80 * 2
CLD
MOV AH, 7
NEXT3:
LODSB
CMP AL, 0
JZ OVER3
STOSW
JMP NEXT3
OVER3:
MOV AX, GDTNULL
MOV DS, AX
MOV ES, AX
DW 340FH ;SYSENTER
CODE3 ENDS
END START