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

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


db 0x00
datasel equ $-gdt
data_gdt
dw 0x0ffff
dw 0x0000
db 0x00
db 0x092
db 0x0cf
db 0x00
videosel equ $-gdt
dw 3999
dw 0x8000 ; 基址是0xb8000
db 0x0b
db 0x92
db 0x00
db 0x00
gdt_end
times 510-($-$$) db 0
dw 0x0aa55
把上面的代碼存在一個(gè)名為abc.asm的文件之中,使用命令nasm abc.asm,將得出一個(gè)名為abc的文件 。然后插入軟盤,輸入命令:dd if=abc of=/dev/fd0 。該命令將把文件abc寫入到軟盤的第一扇區(qū)之中 。然后重新啟動系統(tǒng),就會看到如下的信息:*Our os booting................
* A (棕色)
* Switching to protected mode....
* A (白色)
對代碼的解釋上面給出了所有的代碼,下面我對上述代碼做一些解釋 ?!?使用的函數(shù)下面是代碼中一些函數(shù)的說明:print_mesg 該子程序使用了BIOS中斷10h的功能13h,即向屏幕寫一字符串 。屬性控制是通過向一些寄存器中送入不同的值來實(shí)現(xiàn)的 。中斷10h是用于各種字符串操作,我們把子功能號13h送到ah中,用于指明要打印一個(gè)字符串 。al寄存器中的0說明了光標(biāo)返回的起始位置,0表示調(diào)用函數(shù)后光標(biāo)返回到下一行的行首 。如果al為1則表示光標(biāo)位于最后一個(gè)字符處 。顯存被分成了幾頁,在同一時(shí)刻只能顯示其中的一頁 。bh指明的是頁號;bl則指明要顯示字符的顏色;cx指明要顯示字符串的長度;dx指明光標(biāo)的位置(即起始的行和列) 。所有相關(guān)寄存器初始化完成以后,就可以調(diào)用BIOS中斷10h了 。get_key 使用中斷16h的子功能00h,從屏幕得到下一個(gè)字符 。clrscr 該函數(shù)使用了中斷10h的另外一個(gè)子功能06h,用于輸出開始前清屏 。初始化時(shí)給al中送入0 。寄存器cx和dx指明要清屏的屏幕范圍,在本例中是整個(gè)屏幕 。寄存器bh指明屏幕填充的顏色,在本例中是黑色 ?!?其它內(nèi)容程序一開始是一條短跳轉(zhuǎn)指令,跳到begin_boot處 。在實(shí)模式下,在此打印一個(gè)棕色的“A”,并且設(shè)置一個(gè)GDT 。切換到保護(hù)模式,并且打印一個(gè)白色的“A” 。這兩種模式使用的都是自己的尋址方法 。在實(shí)模式下,使用段寄存器gs指示顯存位置,我們使用的是CGA顯卡(默認(rèn)基址是0xb8000) 。在代碼中是不是漏了一個(gè)0呢?沒有,因?yàn)閷?shí)模式下會提供一個(gè)附加的0 。這種方式也被80386繼承下來了 。A的ASCⅡ是0x41,0x06指明了需要一個(gè)棕色的字符 。該顯示會一直持續(xù)直至按下任意鍵 。下面要在屏幕上顯示一句話,告訴使用者下面馬上要進(jìn)入保護(hù)模式了 。啟動到保護(hù)模式,在進(jìn)行切換時(shí)不希望此時(shí)有中斷的影響,故要關(guān)閉所有的中斷(使用cli來實(shí)現(xiàn)) 。然后對GDT初始化 。在整個(gè)切換過程中,對4個(gè)描述符進(jìn)行了初始化 。這些描述符對代碼段(code_gdt)、數(shù)據(jù)和堆棧段(data_gdt),以及為了訪問顯存而對顯示段進(jìn)行初始化 。此外,還會對一個(gè)空描述符進(jìn)行初始化 。GDT的基址要加載至GDTR系統(tǒng)寄存器之中 。gdtr段的第一個(gè)字加載的是GDT的大小,在下一個(gè)雙字中則加載的是基址 。然后,lgdt指令把把gdt段加載至GDTR寄存器中 。現(xiàn)在已經(jīng)做好了切換到保護(hù)模式前的所有準(zhǔn)備 。最后一件事情就是把CR0寄存器的PE位置1 。不過,即使這樣還沒有處于保護(hù)模式狀態(tài)之下 。設(shè)置了PE位以后,還需要通過執(zhí)行JMP指令來清除處理器指令預(yù)取隊(duì)列 。在80386中,使用指令前總是先將其從內(nèi)存中取出,并且進(jìn)行解碼和尋址 。然而,當(dāng)進(jìn)入保護(hù)模式以后,預(yù)取指令信息(它還處于實(shí)地址模式)就無效了 。使用JMP指令的目的就是強(qiáng)迫處理器放棄無效的信息 。現(xiàn)在,已經(jīng)在保護(hù)模式下了 。那么,如何檢測是在保護(hù)模式狀態(tài)之下呢?讓我們來看一看屏幕上這個(gè)白色的字母A 。在這里,使用了數(shù)據(jù)段選擇符(datase1)對數(shù)據(jù)段和附加段進(jìn)行了初始化,使用顯示段選擇符(videose1)對gs進(jìn)行了初始化 。告示的字符“A”其ASCⅡ值和屬性位于[gs:0000]處,也就是b8000:0000處 。循環(huán)語句使得該字符一直在屏幕上顯示,直至重新啟動系統(tǒng) 。下一步要做的事現(xiàn)在,這個(gè)操作系統(tǒng)已經(jīng)工作在保護(hù)模式下了,但是實(shí)際上它并不實(shí)現(xiàn)什么具體的功能 。你可以在這個(gè)基礎(chǔ)上為它增加各種操作系統(tǒng)所具有的功能 。我們自己動手寫操作系統(tǒng)到此也就告一段落 。

推薦閱讀