分析之前書上寫的Boot sector(引導扇區) , 加上一些不懂的 , 經過查找和看書...把一些理解原理記下來,有路過的PRO user..如有錯誤,請一定要指正小弟 ! 感激不盡 :D
先來看整個x86的開機啟動過程,這裡有分1st Bootload和2nd Bootload,大體可以這樣表示 :
1.電源開啟
2.CPU進行Reset工作
3.從BIOS的ROM中第FFF:0000位址開始執行General Bootloader
4.進行POST(開機自檢,Powe On Self Test)動作
5.讀取CMOS設定資料
6.讀取所選的磁碟機的CHS 0:0:1的磁區
7.從記憶體第0x7C00的位址開始執行2nd Bootload
註:CHS -- 指定磁區位置的方式,Cylinder: Head: Sector,0:0:1就代表第0個Cylinder(面)、第0個Head(磁軌)、第1個Sector(扇區)
其中3~7的動作就是1st Bootload,它是放在BIOS裡面的,我們沒辦法去對它做修改,因為這些是原廠出廠時就己經寫死了.
所以我們能自行撰寫2nd Bootload以及讓2nd Bootload跳轉至作業系統,但是有幾個規定要特別記住 :
1.這時只有單純CPU工作,作業系統完全沒被載入,所以我們僅能使用CPU指令,硬體I/O,BIOS中斷能使用而己,也就是說....想用C來寫2nd Bootload是不可能的 XD (除非有另外的函式庫....)
2.一個Sector的大小就是512Kbyte,據說是硬體規格(沒查證.....),也就是說....要寫出2nd Bootload,一定要把512Kbyte填滿 !
簡單來說,一旦BIOS發現了在0:0:1的開機磁區,就會把Sector(512Kbyte)的內容裝載到記憶體位址的0000:07C00處,然後再跳轉到0x7C00處將控制權全都交給這段(sector)開機程式碼,從這裡開始,電腦就不再由BIOS中固有的程式來控制,而變成作業系統的一部份來控制.
註:ROM BIOS的INT 19H(引導加載程序,相當於熱啟動系統) 固定裝入記憶體的0000:7C00H
所以,在2nd Bootload的程式碼開頭,一定要告訴CPU說,接下來的這些程式碼,是從0x7C00的地址開始的.
瞭解整個系統開機運作後,就可以來分析書上所提供的2nd Bootload程式碼 :
1 org 07c00h
2 mov ax, cs
3 mov ds, ax
4 mov es, ax
5 call DispStr
6 jmp $
7 DispStr:
8 mov ax, BootMessage
9 mov bp, ax
10 mov cx, 16
11 mov ax, 01301h
12 mov bx, 000ch
13 mov dl, 0
14 int 10h
15 ret
16 BootMessage: db "Hello, OS world!"
17 times 510-($-$$) db 0
18 dw 0xaa55
雖然書上的程式碼都有註解,但我還是一一分析...畢竟我組語完全不熟....T_T
註: 8086CPU一共有14個暫存器,先介紹等下會用到的暫存器
通用暫存器:AX、BX、CX、DX
(可獨立8位元使用 , AH和AL , 最大值僅能0~255)
段暫存器 : CS、SS、DS、ES、PSW
可間接定址暫存器:BP
1行 : 調整偏移量偽指令ORG,指定下面的指令從7c00h處開始,因為BIOS一旦發現引導扇區,就會將這512字節裝載到記憶體的0000:7c00處
2行:將CS(Code Seg,程式暫存器)內容放到AX(通用暫存器)
3~4行:同樣將DS,ES暫存器指向AX,這樣一來,CS,DS,ES將指向相同的segment
5行: call function "DispStr"
6行:call function完之後,將跳到相同的地址,也就是它會無窮迴圈. $代表當前所在的位址
8行:將BootMessage內容放進AX
9行:AX內容放進BP,亦即BP同樣指向BootMessage
10行:長度為16的字符串放進CX
11行:AH=13h,int 10h啟用視頻中斷13H號功能 , AL=01代表寫完字符串之後,更新光標位置
12行:BH=0H,頁號(視頻緩衝區是分頁的...恩...這我也不懂XD) , BL=0CH代表字符顯示屬性
13行:DH和DL寫字符串的光標位置,DH=行號,DL=列號 (不知道為啥DX就是寫字符串的暫存器...是定義就這樣子嗎?? 哎...要查查= =)
14行:啟用10h號中斷
15行:跟return一樣的道理...
16行:把BootMessage定義為Hello的字串,就如同#define一樣XD
17行:$是當前地址,$$是首地址,也就是說,從這樣開始一直到510處,全用0填充
18行:這滿重要的,其中的511和512地址是專門用來判斷是否為一個Boot Sector,0xAA55就是Boot Sector一個結束標誌
No comments:
Post a Comment