保护模式下的编程<三>

类别:编程语言 点击:0 评论:0 推荐:

在上一节我们讲了GDT的用法,这一节我要讲讲LDT的用法,呵呵.以下是源代码:

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

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

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

descriptor       struc                       ;//描述符的结构

limitl       dw   0

basel       dw   0

basem     db    0

attributes dw   0

baseh      db    0

descriptor       ends

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

pdesc      struc                              ;//伪描述府   

limit dw   0

base dd    0

pdesc      ends

;

atdw=92h

atce=98h

atcer=9ah

atldt=82h

TIL=04H

                            .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

;局部描述表的描述符

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,>           

vcode_sel=(vcode-ldt)+TIL          

;要显示的数据

vdata       descriptor       <0FFFFh,,,atdw,>

vdata_sel=(vdata-ldt)+TIL

;要显示的数据2

vdata1       descriptor       <0FFFFh,,,atdw,>

vdata1_sel=(vdata1-ldt)+TIL

;            

vbuf    descriptor      <0FFFFh,8000h,0bh,atdw,>

vbuf_sel=(vbuf-ldt)+TIL  

ldtseg      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

gojump: jump    <code_sel>,<offset toreal>

vcseg   ends

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

codekseg       segment         use16

       assume       cs:codekseg

startk:     mov       ax,ldt_sel

       lldt   ax

       jump       <vcode_sel>,<offset vstart>

 

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

       ;

       push       ds

      

       mov       ax,ldtseg

       mov ds,ax

       assume       ds:ldtseg

      

       mov     ax,vcseg

        mul     bx

        mov     word    ptr     vcode.basel,ax

        mov     byte    ptr     vcode.basem,dl

        mov     byte    ptr     vcode.baseh,dh

        ;

        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

        pop       ds

        ;

        assume       ds:gdtseg

        lgdt    qword   ptr     vgdtr

       cli

       ea20                                     ; //

       mov       eax,cr0                         ; //    进入保护模式

       or    eax,1                            ; //      

       mov       cr0,eax                           ;//

       jump       <codek_sel>,<offset startk>      ; //  proctect mode

      

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

       这段代码,我们可以用前面的图来表示.要用LDT,我们需要用到mov       ax,gdtseg ,lldt    ax这两个命令是把全局描述表送入局部描述表寄存器.在执行玩这两个命令后,我们就可以使用局部描述符中的描述表所指向的段了.呵呵.

本文地址:http://com.8s8s.com/it/it28903.htm