红色为批注,;$$为问题
%include "F:\虚拟机\玩转文件\pm.inc"
org 0100h
jmp Code16
[SECTION .des]
LABLE_GDT : Descriptor 0,0,0
LABEL_DESC_NORMAL: Descriptor 0, 0ffffh,92h;;Normal描述符
LABLE_CODE32 : Descriptor 0,SEGCODE32,4098H;;非一致代码段--32位
LABLE_DATA32 : Descriptor 0,SEGDATA32,92H;
LABEL_DESC_VIDEO : Descriptor 0B8000h,0ffffh, 92H;
LABLE_CODE16 : Descriptor 0,0ffffh,98H;;16位非一致代码段
;$可写?后续的过程中会往此描述符指向的代码段里改变某量$
GdtLen equ $-LABLE_GDT
GdtPtr dw GdtLen-1
dd 0
SelectorNormal equ LABEL_DESC_NORMAL - LABLE_GDT;Normal选择子
seclectorcode32 equ LABLE_CODE32 - LABLE_GDT
seclectorcode16 equ LABLE_CODE16 - LABLE_GDT;16位代码段选择子
seclectordata32 equ LABLE_DATA32 - LABLE_GDT
SelectorVideo equ LABEL_DESC_VIDEO - LABLE_GDT
[SECTION .data]
ALIGN 32 ;
[BITS 32]
Data32 db "In protect model Now.LYHL",0
DataF equ Data32 - $$
Data16 db "In real model Now。LYHL ",0
DataN equ Data16 - $$
SEGDATA32 equ $-Data32
[SECTION .ccode16]
[BITS 16]
Code16: ;-
MOV AX,CS
MOV DS,AX
mov es,ax
;
mov [ww+3],ax;$此处直接把ax的值写入16位代码段出,有无更好地办法?$
XOR EAX,EAX
mov ax,cs
SHL EAX,4
ADD EAX,Data32
mov [LABLE_DATA32+2],ax
shr eax,16 ;;
mov [LABLE_DATA32+4],al
mov [LABLE_DATA32+7],ah;36
XOR EAX,EAX
mov ax,cs
SHL EAX,4
ADD EAX,Code32
mov [LABLE_CODE32+2],ax
shr eax,16
mov [LABLE_CODE32+4],al;----------------------------50
mov [LABLE_CODE32+7],ah
;初始化 16位代码段 描述符
XOR EAX,EAX
mov ax,cs
SHL EAX,4
ADD EAX,MCode16
mov [LABLE_CODE16+2],ax
shr eax,16
mov [LABLE_CODE16+4],al;-
mov [LABLE_CODE16+7],ah
xor eax,eax
mov ax,ds
shl eax,4
add eax,LABLE_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 seclectorcode32:0;--
LABEL_REAL:
mov ax,cs
mov ds, ax
mov es, ax
mov ss, ax
IN AL,92H
AND AL,11111101b
OUT 92H,AL
sti;----
mov ax,0B800h
mov es,ax
mov cx,10
mov edi,(80*5+5)*2
mov ah,0Ch
mov esi,Data16
sv:
mov al,[ds:esi]
test al,al;----
jz ddos
mov [es:edi],ax
inc esi;-------------------------110
add edi,2
jmp sv
ddos:
MOV AX,4C00H
INT 21H
[SECTION .code32];-----
[BITS 32]
Code32:
xor eax,eax;-------
mov ax,seclectordata32
mov ds,ax
xor edi,edi
mov edi,(80*10+0)*2
xor esi,esi
mov esi,DataF ;源数据偏移地址
mov ax,SelectorVideo
mov gs, ax;-----
mov ah,0Ch
xy:
mov al,[esi]
test al,al;----- ;判断是否是最后一个字符
jz qq
mov [gs:edi],ax
inc esi;-------
add edi,2
jmp xy
qq:
jmp seclectorcode16:0 ;$保护模式进入16位代码段不会受影响?16,32位代码段的$
;$区别在什么地方?CPU又怎么知道按多少位来取出对应的$
;$数据或者代码?$
SEGCODE32 equ $-Code32
[SECTION .code16] ;$为什么非要经过此步骤?高速描述符缓冲寄存器怎么回事?$
[BITS 16]
MCode16:
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 ;回到实模式
ww:
jmp 0:LABEL_REAL;------ ;此处的0已经发生改变