?
1 介紹文本編輯器
?
這部分可直接略過
?
2 繼續開發
?
helloos.nas中核心程序之前的內容和啟動區以外的內容先不講了,因為還涉及到一些軟盤方面的知識。
然后來講的是helloos.nas這個文件
?
; hello-os ; TAB=4 ORG 0x7c00 ; 指明程序的裝載地址; 以下這部分記錄的是FAT12格式的軟盤JMP entryDB 0x90DB "HELLOIPL" ; 啟動扇區的名稱可以是任意的字符串 (8字節)DW 512 ; 每個扇區(sector)的大小(必須是512字節)DB 1 ; 簇(cluster)的大小 (必須為512字節)DW 1 ; FAT的起始位置 (一般從第一個扇區開始)DB 2 ; FAT的個數 (必須為2)DW 224 ; 根目錄的大小(一般設成224項)DW 2880 ; 該磁盤的大小(必須是2880扇區)DB 0xf0 ; 磁盤的種類 (必須是0xf0)DW 9 ; FAT的長度 (必須是9扇區)DW 18 ; 1個磁道(track)有幾個扇區(必須是18)DW 2 ; 磁頭數 (必須是2)DD 0 ; 不使用分區, 必須是0DD 2880 ; 重寫一次磁盤大小DB 0,0,0x29 ; 意義不明, 固定DD 0xffffffff ; (可能是)卷標號碼DB "HELLO-OS " ; 磁盤的名稱(11字節)DB "FAT12 " ; 磁盤格式名稱 (8字節)RESB 18 ; 先空出18字節; 程序主體entry:MOV AX,0 ; 初始化寄存器MOV SS,AXMOV SP,0x7c00MOV DS,AXMOV ES,AXMOV SI,msg putloop:MOV AL,[SI]ADD SI,1 ; 給SI加1CMP AL,0JE finMOV AH,0x0e ; 顯示一個文字MOV BX,15 ; 指定字符顏色INT 0x10 ; 調用顯卡BIOSJMP putloop fin:HLT ; 讓CPU停止等待指令JMP fin ; 無限循環msg:DB 0x0a, 0x0a ; 換行2次DB "hello, world"DB 0x0a ; 換行DB 0RESB 0x7dfe-$ ; 填寫0x00, 直到0x7dfeDB 0x55, 0xaa; 以下是啟動區以外部分的輸出 DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00RESB 4600DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00RESB 1469432
?
ORG指令
?
ORG指令告訴nask,在開始執行的時候,把這些機器語言指令裝載到內存中的哪個地址。
這條指令使得$的含義也發生了變化,不再是指輸出文件的第幾個字節,而是代表將要讀入的內存地址。
?
ORG是"origin","源頭、起點"的意思,它會告訴nask,程序要從指定的這個地址開始也就是要把程序裝載到內存中的指定地址。
?
JMP,JE指令
相當于C語言中的goto標簽,多年以來我們都被教育不要用goto......
"JMP entry"這個指令就是讓CPU執行內存地址為entry處的程序。
標簽
在上面的程序中entry,fin,putloop和msg都是標簽,相當于一個入口地址,或者標記。
每個標號對應的數字,都是由匯編語言編譯器根據ORG指令計算出來的。編譯器計算出的"標號的地方對應的內存地址"就是那個標號的值。
?
MOV指令
?
CPU中的各種寄存器
?
匯編中[]取值
?
MOV AL, SI的意思是將SI寄存器中的值傳給AL寄存器,但是MOV AL, [SI]的意思將SI中存儲著一個數字,而這個數字代表的是內存中的一個地址,[SI]意思是取出這個地址應對的值。
?
MOV BYTE [678], 123
MOV WORD [678], 123
?
數據大小端的問題
?
INT指令
?
INT是軟件中斷指令。意思是打斷CPU當前的執行路徑,跑去其他的地方執行。
BIOS中存儲了為開發人員準備的各種函數的集合,INT指令后面接不通的數字,就調用BIOS中對應的函數了。
?
HLT指令
HLT讓CPU停止動作的指令,不過并不是徹底的停止,而是讓CPU進行待機狀態,只要外部發生變化,比如按下鼠標鍵盤,就會醒過來,繼續執行程序。
如果沒有HLT指令,CPU會不停的只去執行JMP指令,負荷達到100%,非常費電。
?
0x7c00
?
現在的內存地址都很大了,尼瑪,內存今年漲價好厲害。
內存的0號地址,也就是最開始的地方,是BIOS程序用來實現各種不同功能的地方,如果隨便使用就會與BIOS發生沖突。
此外,在內存的0xf0000號地址附近還存放著BIOS程序本身,也不能使用。
內存還有不少地方也是不能使用的,作為操作系統開發者要特別注意。
?
0x00007c00~0x00007dff:啟動區內容的裝載地址
?
程序中ORG指令指的就是這個地址。
?
文中沒有解釋為啥是0x7C00,我又在網上找了一下
?
一下內容來自阮一峰老師博客
=================== start_1 =======================
《計算機原理》課本說,啟動時,主引導記錄會存入內存地址0x7C00。
這個奇怪的地址,是怎么來的,課本就不解釋了。我一直有疑問,為什么不存入內存的頭部、尾部、或者其他位置,而偏偏存入這個比 32KB 小1024字節的地方?
昨天,我讀到一篇文章,終于解開了這個謎。
首先,如果你不知道,主引導記錄(Master boot record,縮寫為MBR)是什么,可以先讀《計算機是如何啟動的?》。
簡單說,計算機啟動是這樣一個過程。
- 通電
- 讀取ROM里面的BIOS,用來檢查硬件
- 硬件檢查通過
- BIOS根據指定的順序,檢查引導設備的第一個扇區(即主引導記錄),加載在內存地址 0x7C00
- 主引導記錄把操作權交給操作系統
所以,主引導記錄就是引導"操作系統"進入內存的一段小程序,大小不超過1個扇區(512字節)。
0x7C00這個地址來自Intel的第一代個人電腦芯片8088,以后的CPU為了保持兼容,一直使用這個地址。
1981年8月,IBM公司最早的個人電腦IBM PC 5150上市,就用了這個芯片。
當時,搭配的操作系統是86-DOS。這個操作系統需要的內存最少是32KB。我們知道,內存地址從0x0000開始編號,32KB的內存就是0x0000~0x7FFF。
8088芯片本身需要占用0x0000~0x03FF,用來保存各種中斷處理程序的儲存位置。(主引導記錄本身就是中斷信號INT 19h的處理程序。)所以,內存只剩下0x0400~0x7FFF可以使用。
為了把盡量多的連續內存留給操作系統,主引導記錄就被放到了內存地址的尾部。由于一個扇區是512字節,主引導記錄本身也會產生數據,需要另外留出512字節保存。所以,它的預留位置就變成了:
0x7FFF - 512 - 512 + 1 = 0x7C00
0x7C00就是這樣來的。
計算機啟動后,32KB內存的使用情況如下。
=================== end_1 =======================
就欣賞阮老師挖到底的情懷
?
所以其實啟動區就放到了0x7c00的位置,比32KB少1KB,記住這個,到時候裝個B。
?
?
3 先制作啟動區
?
這里作者說并不想用nask來制作整個磁盤映像,而是先只用它來制作啟動區,去掉了后半段,程序也改名為ipl.nas。
?
大概就是這一段內容去掉了,就是只留到了55 AA了,還記得55AA了,第一個扇區最后的兩個字節哦。
?
4 Makefile入門
?
這里就不講了,就是把來需要手動輸入的編譯命令用寫成Makefile這個文件。
?
數據也能執行么?
CPU執行的是啥,指令,指令就是數據,CPU先找指令,再找操作數。你隨便給一段數據CPU,CPU也能執行。
這里的意思就是,瞎幾把給CPU傳指令和數據,CPU執行的結果坑定也是亂七八糟的。