测试环境:Win98下的DOS7,用MASM6.11编译。
流程如下:
实模式(16位,RING0)
|
|
保护模式(32位, RING 0) -->发生INT 2EH中断,并返回(IRETD)
|
|
保护模式(16位, RING0)
|
|
实模式(16位, RING0)
.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
IDTR STRUC
LIMIT DW 0
BASE DD 0
IDTR ENDS
GATE STRUC
OFFL DW 0
SEL DW 0
ATTR DW 0
OFFH DW 0
GATE ENDS
STACK SEGMENT USE16
DB 256 DUP (0)
STACKLEN = $
STACK ENDS
DATA SEGMENT USE16
GDT DESC <>
GDTNULL = 0
GDTDATA DESC <0FFFFH, 0, 0, 92H, 0>
GDTDATASEL = OFFSET GDTDATA - OFFSET GDT
GDTCODE DESC <0FFFFH, 0, 0, 98H, 0>
GDTCODESEL = OFFSET GDTCODE - OFFSET GDT
GDTSTACK DESC <0FFFFH, 0, 0, 92H, 0>
GDTSTACKSEL = OFFSET GDTSTACK - OFFSET GDT
GDTDATA32 DESC <0FFFFH, 0, 0, 4092H, 0>
GDTDATA32SEL = OFFSET GDTDATA32 - OFFSET GDT
GDTSTACK32 DESC <0FFFFH, 0, 0, 4092H, 0>
GDTSTACK32SEL = OFFSET GDTSTACK32 - OFFSET GDT
GDTCODE32 DESC <0FFFFH, 0, 0, 4098H, 0>
GDTCODE32SEL = OFFSET GDTCODE32 - OFFSET GDT
GDTDISP DESC <0FFFFH, 8000H, 0BH, 92H, 0>
GDTDISPSEL = OFFSET GDTDISP - OFFSET GDT
NEWGDTR GDTR <OFFSET NEWGDTR - OFFSET GDT, 0>
OLDGDTR GDTR <>
IDT GATE 2EH DUP (<>)
GATE <OFFSET MYINT2EH, GDTCODE32SEL, 8F00H, 0>
NEWIDTR IDTR <OFFSET NEWIDTR - OFFSET IDT, 0>
OLDIDTR IDTR <>
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, DATA
MOV BX, 10H
MUL BX
ADD AX, OFFSET IDT
ADC DX, 0
MOV WORD PTR NEWIDTR.BASE, AX
MOV WORD PTR NEWIDTR.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, CODE32
MOV BX, 10H
MUL BX
MOV GDTCODE32.BASEL, AX
MOV GDTCODE32.BASEM, DL
MOV GDTCODE32.BASEH, DH
MOV AX, STACK32
MOV BX, 10H
MUL BX
MOV GDTSTACK32.BASEL, AX
MOV GDTSTACK32.BASEM, DL
MOV GDTSTACK32.BASEH, DH
MOV AX, DATA32
MOV BX, 10H
MUL BX
MOV GDTDATA32.BASEL, AX
MOV GDTDATA32.BASEM, DL
MOV GDTDATA32.BASEH, DH
CLI
SGDT FWORD PTR OLDGDTR
LGDT FWORD PTR NEWGDTR
SIDT FWORD PTR OLDIDTR
LIDT FWORD PTR NEWIDTR
MOV EAX, CR0
OR EAX, 1
MOV CR0, EAX
DB 0EAH
DW 0
DW GDTCODE32SEL
PROTECT:
MOV AX, GDTDATASEL
MOV DS, AX
MOV AX, GDTSTACKSEL
MOV SS, AX
MOV EAX, CR0
AND EAX, 0FFFFFFFEH
MOV CR0, EAX
DB 0EAH
DW OFFSET REAL
DW SEG REAL
REAL:
MOV AX, DATA
MOV DS, AX
MOV AX, STACK
MOV SS, AX
MOV SP, STACKLEN
MOV AX, 0
MOV ES, AX
MOV FS, AX
MOV GS, AX
LGDT FWORD PTR OLDGDTR
LIDT FWORD PTR OLDIDTR
STI
MOV AH, 4CH
INT 21H
CODE ENDS
DATA32 SEGMENT USE32
MESS32 DB 'HELLO WORLD!', 0
DATA32 ENDS
STACK32 SEGMENT USE32
DB 256 DUP (0)
STACK32LEN = $
STACK32 ENDS
CODE32 SEGMENT USE32
ASSUME DS:DATA32, CS:CODE32, SS:STACK32
MOV AX, GDTDATA32SEL
MOV DS, AX
MOV AX, GDTNULL
MOV GS, AX
MOV FS, AX
MOV ES, AX
MOV AX, GDTSTACK32SEL
MOV SS, AX
MOV ESP, STACK32LEN
;
INT 2EH
DB 0EAH
DW OFFSET PROTECT
DW 0
DW GDTCODESEL
MYINT2EH:
MOV AX, GDTDISPSEL
MOV ES, AX
MOV AX, GDTDATA32SEL
MOV DS, AX
MOV EDI, 0
MOV ESI, OFFSET MESS32
CLD
MOV AH, 7
NEXT32:
LODSB
CMP AL, 0
JZ OVER32
STOSW
JMP NEXT32
OVER32:
IRETD
CODE32 ENDS
END START