保护模式编程<五>

来源:互联网 发布:java 微信开发 编辑:程序博客网 时间:2024/05/01 21:55

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

 

原创粉丝点击