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