操作系统开发小试-保护模式引导程序
+------------------------------------------------+%include "pm.inc"
操作系统开发小试-保护模式引导程序
+------------------------------------------------+
+
+1.开发语言:ASM(工具:NASM)
+2.虚拟环境:Virtual PC
+3.应用工具:WinHex Ver11.2
======================================================
;%define _BOOT_DEBUG_
%ifdef _BOOT_DEBUG_
org 00100h
%else
org 07c00h
%endif
jmp begin_boot ; 跳过其它的数据,跳转到引导程序的开始处
print_mesg: ; 打印信息调用
mov ah, 0x13 ; 使用中断10h的功能13,在屏幕上写一个字符串
mov al, 0x00 ; 决定调用函数后光标所处的位置
mov bx, 0x0007 ; 设置显示属性
mov cx, 0x20 ; 在此字符串长度为32
mov dx, 0x0000 ; 光标的起始行和列
int 0x10
ret
get_key: ;等待按键
mov ah, 0x00
int 0x16 ; Get_key使用中断16h的功能0,读取下一个字符
ret
clrscr: ; 清屏
mov ax, 0x0600 ; 使用中断10h的功能6,实现卷屏,如果al=0则清屏
mov cx, 0x0000 ; 清屏
mov dx, 0x174f ; 卷屏至23,79
mov bh, 0 ; 使用颜色0来填充
int 0x10
ret
bits 16
;gdt
LABEL_DESC_NULL: Descriptor 0, 0, 0
LABEL_DESC_CODE32: Descriptor 0, SegCode32Len-1, DA_C + DA_32
LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW
gdtr dw $ - LABEL_DESC_NULL
dd LABEL_DESC_NULL
SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_DESC_NULL
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_DESC_NULL
bootmesg db "Our OS boot sector loading... "
pm_mesg db "Switching to protected mode... "
begin_boot: ; 引导程序开始
mov ax, cs ; 设置段寄存器
mov ds, ax
mov es, ax
call clrscr
mov bp, bootmesg ; 提供字符串地址
call print_mesg
call get_key
bits 16 ; 以16位方式编译
call clrscr
mov ax, 0xb800
mov gs, ax ; 使gs指向显示内存
mov word [gs:0], 0x641 ; 在实模式下显示一个棕色的A
call get_key
mov bp, pm_mesg ; 提供字符串地址
call print_mesg
call get_key
call clrscr
; 设置32位代码段描述符的基地址
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
; 设置GDT物理基地址
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_DESC_NULL
mov dword [gdtr+2], eax
; 加载GDT
lgdt [gdtr]
; 关中断
cli
; 打开A20
in al, 92h
or al, 00000010b
out 92h, al
; 进入保护模式
mov eax, cr0
or al, 1 ; 设置保护模式位
mov cr0, eax
; 跳至32位代码
jmp SelectorCode32:0
bits 32 ; 以32位方式编译
LABEL_SEG_CODE32:
mov ax, SelectorVideo ; 使gs指向显存
mov gs, ax
mov edi, (80*10+40)*2
mov ah, 0ch
mov al, 'P'
mov [gs:edi], ax
jmp $
SegCode32Len equ $ - LABEL_SEG_CODE32
times 510-($-$$) db 0 ; 填满512个字节
dw 0x0AA55 ; 引导扇区标志
评论
发表评论