保护模式下的编程任务切换(源代码)

;--------------------------------------------------------
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
ldtb descriptor <0FFFFh,,,atldt,>
ldtb_sel=ldtb-gdt
tssa descriptor <0FFFFh,,,at386tss,>
tssa_sel=tssa-gdt
tssb descriptor <0FFFFh,,,at386tss,>
tssb_sel=tssb-gdt
tss0 descriptor <0FFFFh,,,at386tss,>
tss0_sel=tss0-gdt
temp descriptor <0FFFFh,,,atce,>
temp_sel=temp-gdt
stack0t descriptor <0ffffh,stack0,,atdw,>
stack0t_sel=stack0t-gdt
stack2t descriptor <0ffffh,stack2,,atdw+dpl2,>
stack2t_sel=(stack2t-gdt)+rpl2
stack3t descriptor <0ffffh,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+rpl3
sega ends
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
segb segment  use16
ldt1 label byte
datab descriptor <0FFFFh,,,atdw+dpl3,>
datab_sel=(datab-ldt1)+TIL+rpl3
codeb   descriptor      <0FFFFh,,,atce+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+rpl3
segb ends
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
tss0seg  segment  use16
 dd 0   ;back
 dw stack0len,0   ;0级堆栈指针
 dw stack0t_sel,0   ;初始化
        dw      0,0                   ;1级堆栈指针
        dw      0,0                     ;初始化
 dw stack2len,0       ;2级堆栈指针
 dw stack2t_sel,0       ;未初始化 
 dd 0   ;cr3
 dw 0,0   ;eip
 dd 0   ;eflags
 dd ?   ;eax
 dd ?   ;ecx
 dd ?   ;edx
 dd ?   ;ebx
 dd stack0len  ;esp
 dd ?   ;ebp
 dd ?   ;esi
 dd ?   ;edi
 dw 0,0   ;es
 dw code_sel,0  ;cs
 dw stack0t_sel,0  ;ss
 dw 0,0   ;ds
        dw      0,0                     ;fs
        dw      0,0                     ;gs
 dw 0,0   ;ldt
 dw 0
 dw $+2   ;指向I/O许可位图
 db 0FFh   ;I/o许可位图结束标志
tss0seg  ends
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
tssbseg  segment  use16
 dd 0   ;back
 dw stack0len,0   ;0级堆栈指针
 dw stack0t_sel,0   ;初始化
        dw      0,0                   ;1级堆栈指针
        dw      0,0                     ;初始化
 dw stack2len,0       ;2级堆栈指针
 dw stack2t_sel,0       ;未初始化 
 dd 0   ;cr3
 dw startb,0  ;eip
 dd 0   ;eflags
 dd ?   ;eax
 dd ?   ;ecx
 dd ?   ;edx
        dd      22                      ;ebx
 dd stack3len  ;esp
 dd ?   ;ebp
 dd ?   ;esi
 dd ?   ;edi
 dw vbufb_sel,0  ;es
 dw codeb_sel,0  ;cs
 dw stack3t_sel,0  ;ss
 dw datab_sel,0  ;ds
        dw      0,0                     ;fs
        dw      0,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                     ;初始化
 dw stack2len,0  ;2级堆栈指针
 dw stack2t_sel,0  ;未初始化 
 dd 0   ;cr3
 dw starta,0  ;eip
 dd 0   ;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,0                     ;fs
        dw      0,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,tss0_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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sseg segment  stack  use16
 dw 256 dup (?)
sseg ends
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
cseg segment  use16 
 assume cs:cseg,ds:gdtseg,ss:sseg
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,tss0seg
 mul bx
 mov word ptr tss0.basel,ax
 mov byte ptr tss0.basem,dl
 mov byte ptr tss0.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,stack0
 mul bx
 mov word ptr stack0t.basel,ax
 mov byte ptr stack0t.basem,dl
 mov byte ptr stack0t.baseh,dh
 ;
 mov ax,stack2
 mul bx
 mov word ptr stack2t.basel,ax
 mov byte ptr stack2t.basem,dl
 mov byte ptr stack2t.baseh,dh
 ;
 mov ax,stack3
 mul bx
 mov word ptr stack3t.basel,ax
 mov byte ptr stack3t.basem,dl
 mov byte ptr stack3t.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
 ea20
 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 ax,sseg
 mov ss,ax
 mov sp,512
 mov ah,4ch
 int 21h
cseg ends
 end start
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值