網上有不少簡單的加載器製作的文章,我也是初學,之前看過《Oranges‘s 一個操作系統的實現》,看到保護模式哪一點覺得非常頭痛,有很多不清楚的地方,現在在看《30天自制操作系統》,雖然讀起來簡單多了,不過我使用的是Linux系統,做起來還是有些麻煩,此係列文章可以當作簡單的學習筆記,不過會加上我個人的理解,將我當初迷茫的地方寫出來,以及如何在Linux系統上搭建起操作系統的實驗環境。最近一年準備主攻編譯器和操作系統,希望能和大家一起學習,進步。
準備環境:
Hello world
org 0x7c00 ; 告知nasm,代碼會加載在0x7c00處,詳細解釋在後面
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
cmp al,0
je fin
mov ah,0x0e
mov bx,15
int 0x10
jmp putloop
fin:
hlt
jmp fin
msg:
db 0x0a,0x0a ; 換行'\n'的ASCII碼爲10=0x0a
db "Hello,world"
db 0x0a
db 0
times 510-($-$$) db 0 ;重複到510字節處
db 0x55,0xaa ;啓動扇區標識
run : bochs a.img
bochs -q #啓動
bin :
nasm -f bin hello.asm -o hello.bin #編譯生成bin格式文件
a.img : bin img
dd if=./hello.bin of=./a.img bs=512 count=1 conv=notrunc #將生成的文件寫入軟盤鏡像
img :
bximage -q -fd -size=1.44 a.img > /dev/null #創建軟盤鏡像
bochs:
cp ~/bochsrc ./ #複製bochsrc到當前目錄,這點實驗的時候看情況更改
clean:
-rm -f hello.bin bochsrc a.img
下面是複製過來的bochsrc###############################################################
# Configuration file for Bochs
###############################################################
# how much memory the emulated machine will have
megs: 32
cpu: ips=10000000
# filename of ROM images
romimage: file=/usr/local/share/bochs/BIOS-bochs-latest
vgaromimage: file=/usr/local/share/bochs/VGABIOS-lgpl-latest
# what disk images will be used
floppya: 1_44=a.img, status=inserted
# choose the boot disk.
boot: floppy
# where do we send log messages?
# log: bochsout.txt
# disable the mouse
mouse: enabled=1
# enable key mapping, using US layout as default.
keyboard_mapping: enabled=1, map=/usr/local/share/bochs/keymaps/x11-pc-us.map
現在,make以下,bochs運行,輸入c(表示繼續,debug版本的bochs),可以看到模擬器上顯示了Hello,world。
00000000 8CC8 mov ax,cs
00000002 8ED0 mov ss,ax
00000004 8ED8 mov ds,ax
00000006 8EC0 mov es,ax
00000008 BE237C mov si,0x7c23
0000000B 8A04 mov al,[si]
0000000D 81C60100 add si,0x1
00000011 3C00 cmp al,0x0
可以看到,mov si,0x7c23 這一條指令,在代碼裏,寫的是 mov si,msg.如果我們去掉前面的org 0x7c00的話,這裏的指令就成了mov si,0x23.顯然,如果其他寄存器都爲0的話,此時下面顯示字符串的指令肯定會出錯,因爲地址有問題。講到這就可以知道,org 0x7c00並不是必須的,我們完全可以使用其他的方式到達同樣的目的,比如像下面這樣修改:jmp 0x7c0:entry
entry:
mov ax,cs
mov ss,ax
mov ds,ax
mov es,ax
mov si,msg
這樣的話,執行跳轉時CS會被設置爲0x7c0,其他寄存器也被下面的指令初始化爲0x7c0,就不會產生問題了。