日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

自己動手寫操作系統(tǒng)( 五 )


圖1 實模式的尋址
圖2 保護(hù)模式下的尋址
圖3 段描述俯的格式此外,還有一個中斷描述符表(IDT) 。這些中斷描述符會告訴處理器到那里可以找到中斷處理程序 。和實模式一樣,每一個中斷都有一個入口,但是這些入口的格式卻完全不同 。因為在切換到保護(hù)模式的過程中沒有使用到IDT,所以在此就不多做介紹了 。進(jìn)入保護(hù)模式80386有4個32位控制寄存器,名字分別為CR0、CR1、CR2和CR3 。CR1是保留在未來處理器中使用的,在80386中沒有定義 。CR0包含系統(tǒng)的控制標(biāo)志,用于控制處理器的操作模式和狀態(tài) 。CR2和CR3是用于控制分頁機(jī)制的 。在此,我們關(guān)注的是CR0寄存器的PE位控制,它負(fù)責(zé)實模式和保護(hù)模式之間的切換 。當(dāng)PE=1時,說明處理器運行于保護(hù)模式之下,其采用的段機(jī)制和前面所述的相應(yīng)內(nèi)容對應(yīng) 。如果PE=0,那么處理器就工作在實模式之下 。切換到保護(hù)模式,實際就是把PE位置為1 。為了把系統(tǒng)切換到保護(hù)模式,還要做一些其它的事情 。程序必須要對系統(tǒng)的段寄存器和控制寄存器進(jìn)行初始化 。把PE位置1后,還要執(zhí)行跳轉(zhuǎn)指令 。過程簡述如下:1.創(chuàng)建GDT表;2.通過置PE位為1進(jìn)入保護(hù)模式;3.執(zhí)行跳轉(zhuǎn)以清除在實模式下讀取的任何指令 。下面使用代碼來實現(xiàn)這個切換過程 。需要的東西◆ 一張空白軟盤◆ NASM編譯器下面是整個程序的源代碼:org 0x07c00; 起始地址是0000:7c00
jmp short begin_boot ; 跳過其它的數(shù)據(jù),跳轉(zhuǎn)到引導(dǎo)程序的開始處
bootmesg db "Our OS boot sector loading ......"
pm_mesg db "Switching to protected mode ...."
dw 512 ; 每一扇區(qū)的字節(jié)數(shù)
db 1 ; 每一簇的扇區(qū)數(shù)
dw 1 ; 保留的扇區(qū)號
db 2
dw 0x00e0
dw 0x0b40
db 0x0f0
dw 9
dw 18
dw 2 ; 讀寫扇區(qū)號
dw 0 ; 隱藏扇區(qū)號
print_mesg :
mov ah,0x13 ; 使用中斷10h的功能13,在屏幕上寫一個字符串
mov al,0x00 ; 決定調(diào)用函數(shù)后光標(biāo)所處的位置
mov bx,0x0007 ; 設(shè)置顯示屬性
mov cx,0x20 ; 在此字符串長度為32
mov dx,0x0000 ; 光標(biāo)的起始行和列
int 0x10 ; 調(diào)用BIOS的中斷10h
ret ; 返回調(diào)用程序
get_key :
mov ah,0x00
int 0x16 ; Get_key使用中斷16h的功能0,讀取下一個字符
ret
clrscr :
mov ax,0x0600 ; 使用中斷10h的功能6,實現(xiàn)卷屏,如果al=0則清屏
mov cx,0x0000 ; 清屏
mov dx,0x174f ; 卷屏至23,79
mov bh,0 ; 使用顏色0來填充
int 0x10 ; 調(diào)用10h中斷
ret
begin_boot :
call clrscr ; 先清屏
mov bp,bootmesg ; 提供串地址
call print_mesg ; 輸出信息
call get_key ; 等待用戶按下任一鍵
bits 16
call clrscr ; 清屏
mov ax,0xb800 ; 使gs指向顯示內(nèi)存
mov gs,ax ; 在實模式下顯示一個棕色的A
mov Word [gs:0],0x641 ; 顯示
call get_key ; 調(diào)用Get_key等待用戶按下任一鍵
mov bp,pm_mesg ; 設(shè)置串指針
call print_mesg ; 調(diào)用print_mesg子程序
call get_key ; 等待按鍵
call clrscr ; 清屏
cli ; 關(guān)中斷
lgdt[gdtr] ; 加載GDT
mov eax,cr0
or al,0x01 ; 設(shè)置保護(hù)模式位
mov cr0,eax ; 將更改后的字送至控制寄存器中
jmp codesel:go_pm
bits 32
go_pm :
mov ax,datasel
mov ds,ax ; 初始化ds和es,使其指向數(shù)據(jù)段
mov es,ax
mov ax,videosel ; 初始化gs,使其指向顯示內(nèi)存
mov gs,ax
mov word [gs:0],0x741 ; 在保護(hù)模式下顯示一個白色的字符A
spin : jmp spin ; 循環(huán)
bits 16
gdtr :
dw gdt_end-gdt-1 ; gdt的長度
dd gdt ; gdt的物理地址
gdt
nullsel equ $-gdt ; $指向當(dāng)前位置,所以nullsel = 0h
gdt0 ; 空描述符
dd 0
dd 0 ; 所有的段描述符都是64位的
codesel equ $-gdt ; 這是8h也就是gdt的第二個描述符
code_gdt
dw 0x0ffff ; 段描述符的界限是4Gb
dw 0x0000
db 0x00
db 0x09a
db 0x0cf

推薦閱讀