- 工作環境
- Lubuntu 17.04
- VMware Workstation 12.5.2
- 參考資料
- Linux 版本筆記:http://lengly.top/archives/85
20170719 - Day_2
- 進度摘要
- 簡易 IPL 製作。
- 完整專案
- 參考資料
一、修改 helloos.nas
RESB 0x7dfe-$
此行無法通過編譯,故修改成TIMES 510-($-$$) DB 0
。$
代表目前行的位址,$$
為目前 section 的位址。(TIMES 意思為重複,先決定次數再確定重複的內容)。
; hello-os
; TAB=4
ORG 0x7c00 ; 指定從 0x7c00 開始執行
; 以下是為了標準 FAT12 格式的軟式磁碟片的記述
JMP entry
DB 0x90
DB "HELLOIPL"
DW 512
DB 1
DW 1
DB 2
DW 224
DW 2880
DB 0xf0
DW 9
DW 18
DW 2
DD 0
DD 2880
DB 0,0,0x29
DD 0xffffffff
DB "HELLO-OS "
DB "FAT12 "
RESB 18
; 程式碼本身
entry:
MOV AX,0 ; 暫存器初始化
MOV SS,AX
MOV SP,0x7c00
MOV DS,AX
MOV ES,AX
MOV SI,msg
putloop:
MOV AL,[SI]
ADD SI,1 ; 在 SI 加 1
CMP AL,0
JE fin
MOV AH,0x0e ; 一個文字表示功能
MOV BX,15 ; 顏色代碼 (color code)
INT 0x10 ; 呼叫視訊 BIOS
JMP putloop
fin:
HLT ; 直到有了某個物件就將 CPU 停止
JMP fin ; 無限迴圈
msg:
DB 0x0a, 0x0a ; 連續兩個換行
DB "hello, world"
DB 0x0a ; 換行
DB 0
; RESB 0x7dfe-$ ; 此行編譯無法通過,故修改成 "TIMES 510-($-$$) DB 0"
TIMES 510-($-$$) DB 0 ; "$" 代表目前行的位址,"$$" 為目前 section 的位址。(TIMES 意思為重複,先確定次數再確定重複的內容)
DB 0x55, 0xaa
二、編譯 helloos.nas
- 編譯
helloos.nas
,在輸出bootloader
的同時也輸出列表檔案ipl.lst
。
nasm -o bootloader -l ipl.lst helloos.nas
- 在 Linux 系統下使用
dd
指令產生os.img
檔案。- 先將 os.img 清空歸零,再將 bootloader 拷貝到 img 裡面。
- 一個軟碟片容量:1.44MB = 512KB * 2880
dd if=/dev/zero of=os.img bs=512 count=2880
dd if=bootloader of=os.img conv=notrunc
if:指定輸入檔案
of:指定輸出檔案
bs:指定 block size,一次讀取與寫入 N 個位元組的資料
count:處理 N 個輸入區塊
- 如果打開
ipl.lst
,可以檢視組合語言轉換成機械碼的情形。
1 ; hello-os
2 ; TAB=4
3
4 ORG 0x7c00 ; 指定從 0x7c00 開始執行
5
6 ; 以下是為了標準 FAT12 格式的軟式磁碟片的記述
7
8 00000000 EB4E JMP entry
9 00000002 90 DB 0x90
10 00000003 48454C4C4F49504C DB "HELLOIPL"
11 0000000B 0002 DW 512
12 0000000D 01 DB 1
13 0000000E 0100 DW 1
14 00000010 02 DB 2
15 00000011 E000 DW 224
16 00000013 400B DW 2880
17 00000015 F0 DB 0xf0
18 00000016 0900 DW 9
19 00000018 1200 DW 18
20 0000001A 0200 DW 2
21 0000001C 00000000 DD 0
22 00000020 400B0000 DD 2880
23 00000024 000029 DB 0,0,0x29
24 00000027 FFFFFFFF DD 0xffffffff
25 0000002B 48454C4C4F2D4F5320- DB "HELLO-OS "
25 00000034 2020
26 00000036 4641543132202020 DB "FAT12 "
27 0000003E <res 00000012> RESB 18
27 ****************** warning: uninitialized space declared in .text section: zeroing
28
29
30
31
32 ; 程式碼本身
33
34 entry:
35 00000050 B80000 MOV AX,0 ; 暫存器初始化
36 00000053 8ED0 MOV SS,AX
37 00000055 BC007C MOV SP,0x7c00
38 00000058 8ED8 MOV DS,AX
39 0000005A 8EC0 MOV ES,AX
40
41 0000005C BE[7400] MOV SI,msg
42
43
44 putloop:
45 0000005F 8A04 MOV AL,[SI]
46 00000061 83C601 ADD SI,1 ; 在 SI 加 1
47 00000064 3C00 CMP AL,0
48 00000066 7409 JE fin
49 00000068 B40E MOV AH,0x0e ; 一個文字表示功能
50 0000006A BB0F00 MOV BX,15 ; 顏色代碼 (color code)
51 0000006D CD10 INT 0x10 ; 呼叫視訊 BIOS
52 0000006F EBEE JMP putloop
53
54
55 fin:
56 00000071 F4 HLT ; 直到有了某個物件就將 CPU 停止
57 00000072 EBFD JMP fin ; 無限迴圈
58
59
60 msg:
61 00000074 0A0A DB 0x0a, 0x0a ; 連續兩個換行
62 00000076 68656C6C6F2C20776F- DB "hello, world"
62 0000007F 726C64
63 00000082 0A DB 0x0a ; 換行
64 00000083 00 DB 0
65
66 ; RESB 0x7dfe-$ ; 此行編譯無法通過,故修改成 "TIMES 510-($-$$) DB 0"
67 00000084 00<rept> TIMES 510-($-$$) DB 0 ; '$' 代表目前行的位址,'$$' 為目前 section 的位址。(TIMES 意思為重複,先確定次數再確定重複的內容)
68
69 000001FE 55AA DB 0x55, 0xaa
三、啟動虛擬機,讀取 os.img
- 執行結果