|
;--------------------------------------------------------
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调用门类型值
attaskgat=85h ;任务门类型
dpl1 = 20h
dpl2 = 40h
dpl3 = 60h
rpl1 = 01h
rpl2 = 02h
rpl3 = 03h
.386P
gdtseg segment use16
gdt label byte
dummy descriptor <>
normal descriptor <0FFFFh,,,atdw,>
normal_sel=normal-gdt
code descriptor <0FFFFh,,,atce,>
code_sel=code-gdt
ldta descriptor <0FFFFh,,,atldt,>
ldta_sel=ldta-gdt
tssa descriptor <0FFFFh,,,at386tss,>
tssa_sel=tssa-gdt
ldtb descriptor <0FFFFh,,,atldt,>
ldtb_sel=ldtb-gdt
tssb descriptor <0FFFFh,,,at386tss,>
tssb_sel=tssb-gdt
temp descriptor <0FFFFh,,,atce,>
temp_sel=temp-gdt
stack0t descriptor <stack0len,stack0,,atdw,>
stack0t_sel=stack0t-gdt
stack2t descriptor <stack2len,stack2,,atdw+dpl2,>
stack2t_sel=(stack2t-gdt)+rpl2
stack3t descriptor <stack3len,stack3,,atdw+dpl3,>
stack3t_sel=(stack3t-gdt)+rpl3
gdtlen=$-gdt
vgdtr pdesc <gdtlen-1,>
gdtseg ends
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sega segment use16
ldt label byte
dataa descriptor <0FFFFh,,,atdw+dpl2,>
dataa_sel=(dataa-ldt)+TIL+rpl2
codea descriptor <0FFFFh,,,atce+dpl2,>
codea_sel=(codea-ldt)+TIL+rpl2
vbufa descriptor <0FFFFh,8000h,0bh,atdw+dpl2,>
vbufa_sel=(vbufa-ldt)+TIL+rpl2
tob descriptor <0,tssb_sel,0,attaskgat+dpl3,0>
tob_sel=(tob-ldt)+TIL
sega ends
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
segb segment use16
ldt1 label byte
datab descriptor <0FFFFh,,,atdw+dpl3,>
datab_sel=(datab-ldt1)+TIL+rpl3
codeb descriptor <0FFFFh,,,atdw+dpl3,>
codeb_sel=(codeb-ldt1)+TIL+rpl3
vbufb descriptor <0FFFFh,8000h,0bh,atdw+dpl3,>
vbufb_sel=(vbufb-ldt1)+TIL+rpl3
torealm gate <tojump,temp_sel,0,at386cgate+dpl3,0>
torealm_sel=(torealm-ldt1)+TIL
segb ends
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
tssbseg segment use16
dd 0 ;back
dw stack0len,0 ;0级堆栈指针
dw stack0t_sel,0 ;初始化
dw 0,0 ;1级堆栈指针
dw 0,0 ;初始化
dd stack2len,0 ;2级堆栈指针
dw stack2t_sel,0 ;未初始化
dd 0 ;cr3
dd startb ;eip
dd ? ;eflags
dd ? ;eax
dd ? ;ecx
dd ? ;edx
dd 20 ;ebx
dd ? ;esp
dd ? ;ebp
dd ? ;esi
dd ? ;edi
dw vbufb_sel,0 ;es
dw codeb_sel,0 ;cs
dw ?,0 ;ss
dw datab_sel,0 ;ds
dw ?,0 ;fs
dw ?,0 ;gs
dw ldtb_sel,0 ;ldt
dw 0
dw $+2 ;指向I/O许可位图
db 0FFh ;I/o许可位图结束标志
tssbseg ends
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
tssaseg segment use16
dd 0 ;back
dw stack0len,0 ;0级堆栈指针
dw stack0t_sel,0 ;初始化
dw 0,0 ;1级堆栈指针
dw 0,0 ;初始化
dd stack2len,0 ;2级堆栈指针
dw stack2t_sel,0 ;未初始化
dd 0 ;cr3
dd starta,0 ;eip
dd ? ;eflags
dd ? ;eax
dd ? ;ecx
dd ? ;edx
dd 0 ;ebx
dd stack2len ;esp
dd ? ;ebp
dd ? ;esi
dd ? ;edi
dw vbufa_sel,0 ;es
dw codea_sel,0 ;cs
dw stack2t_sel,0 ;ss
dw dataa_sel,0 ;ds
dw ?,0 ;fs
dw ?,0 ;gs
dw ldta_sel,0 ;ldt
dw 0
dw $+2 ;指向I/O许可位图
db 0FFh ;I/o许可位图结束标志
tssaseg ends
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dataaseg segment use16
yang db 'how are you',0
dataaseg ends
codeaseg segment use16
assume cs:codeaseg,ds:dataaseg
starta: lea si,yang
mov cx,11
again: mov al,[si]
mov ah,87h
mov es:[bx],ax
add bx,2
inc si
loop again
jump tob_sel,0
codeaseg ends
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
databseg segment use16
hello db 'hello',0
hellolen=$-hello
databseg ends
codebseg segment use16
assume cs:codebseg,ds:databseg
startb: 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 torealm_sel,0 ;任务门
codebseg ends
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
tempseg segment use16
assume cs:tempseg
vitual: mov ax,tssa_sel
ltr ax
jump tssa_sel,0
tojump: jump <code_sel>,<offset toreal>
tempseg ends
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
stack0 segment ;0 stack
stack0len=512
db stack0len dup (0)
stack0 ends
;
stack2 segment ;2 stack
stack2len=512
db stack2len dup (0)
stack2 ends
;
stack3 segment ;3 stack
stack3len=512
db stack3len dup (0)
stack3 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,sega
mul bx
mov word ptr ldta.basel,ax
mov byte ptr ldta.basem,dl
mov byte ptr ldta.baseh,dh
;
mov ax,segb
mul bx
mov word ptr ldtb.basel,ax
mov byte ptr ldtb.basem,dl
mov byte ptr ldtb.baseh,dh
;
mov ax,tssaseg
mul bx
mov word ptr tssa.basel,ax
mov byte ptr tssa.basem,dl
mov byte ptr tssa.baseh,dh
;
mov ax,tssbseg
mul bx
mov word ptr tssb.basel,ax
mov byte ptr tssb.basem,dl
mov byte ptr tssb.baseh,dh
;
mov ax,tempseg
mul bx
mov word ptr temp.basel,ax
mov byte ptr temp.basem,dl
mov byte ptr temp.baseh,dh
;
push ds
assume ds:sega
mov ax,sega
mov ds,ax
;
mov ax,dataaseg
mul bx
mov word ptr dataa.basel,ax
mov byte ptr dataa.basem,dl
mov byte ptr dataa.baseh,dh
;
mov ax,codeaseg
mul bx
mov word ptr codea.basel,ax
mov byte ptr codea.basem,dl
mov byte ptr codea.baseh,dh
;
assume ds:segb
mov ax,segb
mov ds,ax
;
mov ax,databseg
mul bx
mov word ptr datab.basel,ax
mov byte ptr datab.basem,dl
mov byte ptr datab.baseh,dh
;
mov ax,codebseg
mul bx
mov word ptr codeb.basel,ax
mov byte ptr codeb.basem,dl
mov byte ptr codeb.baseh,dh
;
pop ds
assume ds:gdtseg
lgdt qword ptr vgdtr
cli
mov eax,cr0
or ax,1
mov cr0,eax
jump <temp_sel>,<offset vitual>
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
这段代码有什么问题呢?这段代码是实现保护模式下的任务转换 |
|