%macro Descriptor 3
dw %2 & 0FFFFh ; 段界限1
dw %1 & 0FFFFh ; 段基址1
db (%1 >> 16) & 0FFh ; 段基址2
dw ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh) ; 属性1 + 段界限2 + 属性2
db (%1 >> 24) & 0FFh ; 段基址3
%endmacro ; 共 8 字节
org 07c00h
jmp c16
[SECTION .gdt]
;GDT 段基址 段界限 属性
NULL: Descriptor 0, 0, 0 ;空描述符
code: Descriptor 0, Len-1, 98h+4000h;4000h为32位段 98h可执行代码
LDE: Descriptor 0b8000h,0ffffh,92h ;92读写 显存
;GDT结束
GdtLen equ $-NULL ;GDT长度
GdtSize dw GdtLen-1;GDT界限
DD 0 ;GDT基地址
;GDT选择
SetCode32 equ code-NULL ;代码
SetGs equ LDE -NULL ;显存
[SECTION .s16]
[BITS 16]
c16:
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov sp,0100h
;初始化32位代码段
xor eax,eax
mov ax,cs
shl eax,4
add eax,code32
mov word [code+2],ax
shr eax,16
mov byte [code+4],al
mov byte [code+7],ah
;加载GDTR做准备
xor eax,eax
mov ax,ds
shl eax,4
add eax,NULL
mov dword [GdtSize+2],eax
;加载GDTR
lgdt [GdtSize]
;关中断
cli
;打开地址A20
in al,92h
or al,00000010b
out 92h,al
;准备切换到保护模式
mov eax,cr0
or eax,1
mov cr0,eax
;真正进入保护模式
jmp dword SetCode32:0
[SECTION .s32]
[BITS 32]
code32:
mov ax,SetGs
mov gs,ax
jmp $
Len equ $-code32
实模式 跳到保护模式 代码 太长了 不容易理解 谁能帮我把一些没用代码去掉 |