OS——保护模式编程(2)

[section .gdt]    --->  we should give such these definations for the Descriptors in that section

                 LABEL_GDT --> empty Descriptor;

               LABEL_DESC_CODE32 --> turn help to [section .s32]

                 LABEL_DESC_CODE16 --> turn help to [section .s16Code]

               LABEL_DESC_VIDEO  --> the video mm

               LABEL_DESC_DATA  ---> for store the relative data;

               LABEL_DESC_STACK ---> it is a stack in the protect mode ;

                            once you back to real mode; correct the ss and sp;

               LABEL_DESC_TEST -----> view the power for protect mode; this Descriptor is for

                              that; its seg_base is 0500000h =  5MB;  

               LABEL_DESC_NORMAL --->  for backing the real mode, suitable Selector of Descriptor

 

[section .s16Code] --->  the program get in this section from the [section .s32] (jmp SelectorCode16:0)

               note 1:  need a Selector;  -----"SelectorNormal"; when you want to back to real

                      mode, need load a suitable Selector to the relative registers, for the cache

                     of Descriptor can get suitable Seg_base and Seg_Attr!!!!

               note 2:  LABEL_GO_BACK_TO_REAL:  jmp 0:LABEL_REAL_ENTRY;

                     this code is the most wonderful code in this program, I think that;

 

 

[section .s32]    --->  we will fill the all regiters as ds, es, fs, gs, cs, ....... use by Selectors

               then it run in the protect mode, so we should write this codes for testing

               the ability of the protect mode, it said that it can get the 4 GB mm; it is

               powerful, Don't you want to view that ? before we view that power, we have

               to realise two sub_funcion blocks----> TestWrite and TestRead (view the codes)

               as you view the result during the prvious chapter, the function go the Death Circle

               in the end, so we should design this function to return to the Dos OS, to be good end

 

the specific codes:

%include "pm.inc"

org 0100h

  jmp LABEL_BEGIN  

[SECTION .gdt]

LABEL_GDT   Descriptor 0, 0, 0
LABEL_DESC_CODE32 Descriptor 0, SegCode32Len-1, DA_C+DA_32
LABEL_DESC_CODE16: Descriptor 0, 0ffffh, DA_C 
LABEL_DESC_VIDEO Descriptor 0B8000h, 0ffffh,   DA_DRW
LABEL_DESC_DATA  Descriptor  0, DataLen - 1, DA_DRW
LABEL_DESC_TEST  Descriptor 0500000h, 0ffffh, DA_DRW
LABEL_DESC_STACK Descriptor 0, TopOfStack, DA_DRW + DA_32
LABEL_DESC_NORMAL Descriptor  0B8000h, 0ffffh,   DA_DRW

GdtLen equ $ - LABEL_GDT
GdtPtr   dw GdtLen - 1
       dd 0

 

SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT
SelectorCode16 equ LABEL_DESC_CODE16 - LABEL_GDT
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT
; add the new selectors
SelectorData equ LABEL_DESC_DATA - LABEL_GDT
SelectorTest equ LABEL_DESC_TEST - LABEL_GDT
SelectorStack equ LABEL_DESC_STACK - LABEL_GDT
SelectorNormal equ LABEL_DESC_NORMAL - LABEL_GDT

[SECTION .s16]
[BITS 16]
LABEL_BEGIN:
   mov ax, cs
   mov ds, ax
   mov es, ax
   mov ss, ax
   mov sp, 0100h
 
   mov [LABEL_GO_BACK_TO_REAL+3], ax
   mov [SPValueInRealMode], sp ;  处理技巧

  mov ax, cs
  movzx eax, ax
    shl eax, 4
    add eax, LABEL_SEG_CODE16
  mov word [LABEL_DESC_CODE16 + 2], ax
  shr eax, 16
  mov byte [LABEL_DESC_CODE16 + 4], al
  mov byte [LABEL_DESC_CODE16 + 7], ah

  xor eax, eax
  mov ax, cs
  shl eax, 4
  add eax, LABEL_SEG_CODE32
  mov word [LABEL_DESC_CODE32 + 2], ax
  shr eax, 16
  mov byte [LABEL_DESC_CODE32 + 4], al
  mov byte [LABEL_DESC_CODE32 + 7], ah

  xor eax, eax
  mov ax, cs
  shl eax, 4
  add eax, LABEL_DATA
  mov word [LABEL_DESC_DATA + 2], ax
  shr eax, 16
  mov byte [LABEL_DESC_DATA + 4], al
  mov byte [LABEL_DESC_DATA + 7], ah

  xor eax, eax
  mov ax, ds
  shl eax, 4
  add eax, LABEL_STACK
  mov word [LABEL_DESC_STACK + 2], ax
  shr eax, 16
  mov byte [LABEL_DESC_STACK + 4], al
  mov byte [LABEL_DESC_STACK + 7], ah

  xor eax, eax
  mov ax, ds
  shl eax, 4
  add eax, LABEL_GDT
  mov dword [GdtPtr + 2], eax

  lgdt [GdtPtr]
 
  cli
 
  in al, 92h
  or al, 00000010b
  out 92h, al

 

  mov eax, cr0
  or eax, 1
  mov cr0, eax


  jmp dword SelectorCode32:0

 ; back real mode
LABEL_REAL_ENTRY:
   mov ax, cs
   mov ds, ax
   mov es, ax
   mov ss, ax
 
   mov sp, [SPValueInRealMode]
 
   in al, 92h
   and al, 11111101b
   out 92h, al
 
   sti
 
   mov ax, 4c00h
   int 21h
 

 

[SECTION .s32]
[BITS 32]
LABEL_SEG_CODE32:
   mov ax, SelectorVideo
   mov gs, ax
   ; init the es, ds, gs...
   mov ax, SelectorData
   mov ds, ax
   mov ax, SelectorTest
   mov es, ax

   mov ax, SelectorStack
   mov ss, ax
   mov esp,  TopOfStack
 
   mov ah, 0Ch
   xor esi, esi
   xor edi, edi
   mov esi, OffsetPMMessage
   mov edi, (80 * 10 + 0) * 2
   cld
 .1:
   lodsb
   test al, al
   jz .2
   mov [gs:edi], ax
   add edi, 2
   jmp .1
 .2: 

   call DispReturn

   call TestRead  

   call TestWrite  

   call TestRead

   jmp SelectorCode16:0

 

TestRead:

   xor esi, esi  

   mov ecx, 8

 .loop  

   mov al, [es:esi]

   call DispAL

   inc esi  

   loop .loop

  call DispReturn

   ret

 

TestWrite:
   push esi
   push edi
   xor esi, esi
   xor edi, edi
   mov esi, OffsetStrTest
   cld
 .1:
   lodsb
   test al, al
   jz .2
   mov [es:edi], al
   inc edi
   jmp .1
 .2:

   call DispReturn

   ret

DispAL:
   push ecx
   push edx

   mov ah, 0Ch 
   mov dl, al
   shr al, 4
   mov ecx, 2
 .begin:
   and al, 01111b
   cmp al, 9
   ja .1
    add al, '0'
   jmp .2

 .1:  

   sub al, 0Ah

   add al, 'A'

 .2:  

   mov [gs:edi], ax  

   add edi, 2

   mov al, dl  

   loop .begin  

   add edi, 2

  pop edx

  pop ecx

    ret

DispReturn:
   push eax
   push ebx
   mov eax, edi

   mov bl, 160
   div bl
   and eax, 0FFh
   inc eax
   mov bl, 160
   mul bl
   mov edi, eax
   pop ebx
   pop eax

   ret

  SegCode32Len equ $ - LABEL_SEG_CODE32

 

; 数据段; 
[SECTION .data1]
LABEL_DATA:
   SPValueInRealMode dw 0
   PMMessage: dd "In Protect Mode now. ^-^", 0
   OffsetPMMessage equ PMMessage - $$
   StrTest: dd "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0
   OffsetStrTest equ StrTest - $$
 
   DataLen  equ $ - LABEL_DATA

 

; 堆栈段
[SECTION .stack1]
LABEL_STACK:
   times 512 db 0
   TopOfStack equ $ - LABEL_STACK - 1;

 

; 16位代码,由32位代码jmp进入,从32位代码过渡到实模式;
[SECTION .s16Code]
ALIGN 32
[BITS 16]
LABEL_SEG_CODE16:
   mov ax, SelectorNormal
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov gs, ax
   mov ss, ax

 

  mov eax, cr0
   and al, 11111110b
   mov cr0, eax
 
LABEL_GO_BACK_TO_REAL:
   jmp 0:LABEL_REAL_ENTRY
 
   Code16Len  equ $ - LABEL_SEG_CODE16

 

posted @ 2013-07-06 23:51  Auris  阅读(326)  评论(0编辑  收藏  举报