保护模式编程<五>

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

ea20 macro ;//打开A20地址线

push ax

in al,92h

or al,00000010b

out 92h,al

pop ax

endm

;----------------------------------------------------------------------------

;关闭A20地址线

;----------------------------------------------------------------------------

da20 macro

push ax

in al,92h

and al,11111101b

out 92h,al

pop ax

endm

;----------------------------------------------------------------------------

jump macro selector,offsetv ;//跳转宏

db 0EAh

dw offsetv

dw selector

endm

;--------------------

call16 macro selector,offsetv

db 9Ah

dw offsetv

dw selector

endm

;----------------------

descriptor struc ;//描述符的结构

limitl dw 0

basel dw 0

basem db 0

attributes dw 0

baseh db 0

descriptor ends

;-----------------------------------------------------------------------------

gate struc

offsetl dw 0

selector dw 0

dcount db 0

gtype db 0

offseth dw 0

gate ends

;--------------------

pdesc struc ;//伪描述府

limit dw 0

base dd 0

pdesc ends

;

atdw=92h

atce=98h

atcer=9ah

atldt=82h ;局部描述符表段类型值

TIL=04H

at386tss=89h

at386cgate=8ch ;386调用门类型值

dpl1 = 20h

dpl2 = 40h

dpl3 = 60h

rpl1 = 01h

rpl2 = 02h

rpl3 = 03h ;;;;;;;;;;;;;

.386P

gdtseg segment use16

gdt label byte

dummy descriptor <>

;

code descriptor <0FFFFh,,,atce,>

code_sel=code-gdt

;代码段codekseg的描述符

codek descriptor <0FFFFh,,,atce,>

codek_sel=codek-gdt

;通用描述符

normal descriptor <0FFFFh,,,atdw,>

normal_sel=normal-gdt

;

tss descriptor <0FFFFh,,,at386tss,>

tss_sel=tss-gdt

;局部描述表的描述符

ldtable descriptor <0FFFFh,,,atldt,>

ldt_sel=ldtable-gdt

gdtlen=$-gdt

vgdtr pdesc <gdtlen-1,>

gdtseg ends

;------------------------------------------------------------------

;局部描述表

ldtseg segment use16

ldt label byte

;数据段ldtseg的描述符

data descriptor <0FFFFh,,,atdw,>

data_sel=(data-ldt)+TIL

;代码段vcode的描述符

vcode descriptor <0FFFFh,,,atce+dpl3,>

vcode_sel=(vcode-ldt)+TIL+rpl3

;要显示的数据

vdata descriptor <0FFFFh,,,atdw+dpl3,>

vdata_sel=(vdata-ldt)+TIL+rpl3

;要显示的数据2

vdata1 descriptor <0FFFFh,,,atdw+dpl3,>

vdata1_sel=(vdata1-ldt)+TIL+rpl3

;

vbuf descriptor <0FFFFh,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 <tojump,codek_sel,0,at386cgate+dpl3,0> ;;;;;;;;;;;;;;;;;;;

tovbuf_sel=(tovbuf-ldt)+TIL

ldtseg ends

;----------------------------------------------------

tssseg segment use16

dd 0 ;back

dw stack0len,0 ;0级堆栈指针

dw stack0t_sel,0 ;初始化

dw 0,0 ;1级堆栈指针

dw 0,0 ;初始化

dd ? ;2级堆栈指针

dw ?,0 ;未初始化

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 ;指向I/O许可位图

db 0FFh ;I/o许可位图结束标志

tssseg ends

;

stack0 segment

stack0len=512

db stack0len dup (0)

stack0 ends

;

stack3 segment

stack3len=512

db stack3len dup (0)

stack3 ends

;----------------------------------------------------

vdseg segment use16

yang db 'how are you',0

vdseg ends

;-----------------------------------------------------

vdseg1 segment use16

hello db 'hello',0

hellolen=$-hello

vdseg1 ends

;-----------------------------------------------------

vcseg segment use16

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 use16 ;这段代码实现了从0级到3级的转换。很关键的呀!!!!

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 ;建立0级堆栈

push word ptr stack3t_sel ;压如3级堆栈的指针。

push word ptr stack3len

push word ptr vcode_sel ;压入入口地址

push offset vstart

retf ;实现0级到3级的转变

tojump: jump <code_sel>,<offset toreal>

codekseg ends

;????????????????????;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

cseg segment use16

assume cs:cseg,ds:gdtseg

start: 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 <codek_sel>,<offset startk>

toreal: mov ax,normal_sel

mov ds,ax

mov eax,cr0

and eax,0FFFFFFFEH

mov cr0,eax

jump <seg real>,<offset real>

real: da20

sti

mov ah,4ch

int 21h

cseg ends

end start

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航