? ? ? ? 在開(kāi)始之前講個(gè)有意思的笑話虫碉。某日贾惦,一程序猿退休在家,閑來(lái)無(wú)事想學(xué)習(xí)書(shū)法敦捧。開(kāi)始時(shí)候左思右想须板,不知如何下筆,突然靈光一閃提筆寫(xiě)下了幾個(gè)大字兢卵,定睛一看“hello world”逼纸。
所以這里,國(guó)際慣例我這里也是按照hello world開(kāi)始济蝉。OK杰刽。
? ? ? ? 編譯連接完成了以后,這個(gè)代碼必須是在MBR上大小為512個(gè)字節(jié)并且必須要以0xAA55結(jié)束王滤,這里不要問(wèn)我為啥子贺嫂。我也不曉得,估計(jì)這個(gè)需要問(wèn)IBM的PC開(kāi)發(fā)的工程師為啥要這樣定雁乡。開(kāi)機(jī)自檢完成以后PC會(huì)將MBR上的前512個(gè)字節(jié)的程序第喳,讀取到內(nèi)存0x0000:0x07c0處,然后跳轉(zhuǎn)到這個(gè)地址執(zhí)行踱稍,這里執(zhí)行的就是我們的程序曲饱。這個(gè)Hello world 程序相當(dāng)簡(jiǎn)單悠抹,調(diào)用0x10號(hào)中斷,完成清屏和顯示“terrycheng”扩淀。這個(gè)程序我是在ubuntu下面實(shí)際能夠編譯完成楔敌,在bochsrc能夠運(yùn)行的。嘎嘎驻谆。
詳細(xì)代碼:boot.asm
.section .text
.global _start
.code16
#這個(gè)也很重要卵凑,因?yàn)檫@里實(shí)際PC還是在實(shí)模式下,也就說(shuō)為16位的機(jī)器胜臊,所以這里的數(shù)據(jù)都是要16位的勺卢。
.extern main
_start:
movw %cx, %ax
movw %ax, %ds
movw %ax, %es
#上面3行的作用是設(shè)置數(shù)據(jù)段寄存器,這個(gè)時(shí)候PC跳轉(zhuǎn)到了0x0000:0x07c0處象对,所以CX寄存器地址為0x0000黑忱,然而其他的數(shù)據(jù)段確不是這個(gè)地址。
#所以需要設(shè)置和代碼段一樣否則后面的terrycheng這個(gè)數(shù)據(jù)勒魔,是找不到的杨何。
call ClearScreen
#調(diào)用后面的ClearScreen函數(shù),完成清屏沥邻。
movw $msgstr, %bp
movw $10,? ? %cx
call Display
#調(diào)用0x10號(hào)中斷危虱,顯示terrycheng
1:
jmp 1b
#不解釋,死循環(huán)唐全。
ClearScreen:
movw $0x0700,? %ax
movw $0x0000,? %cx
movw $0xFFFF,? %dx
int $0x10
ret
Display:
movw $0x1300, %ax
movw $0,? ? ? %dx
movw $0x000C, %bx
int $0x10
ret
msgstr:
.asciz? "terrycheng"
#terrycheng的數(shù)據(jù)位置埃跷。
len:
.int? ? . - msgstr
#計(jì)算terrycheng的長(zhǎng)度
.org? ? 0x1fe,? 0x00
#進(jìn)行填充,之前我說(shuō)過(guò)的MBR大小必須為512個(gè)字節(jié)邮利,所以這里就把后面的數(shù)據(jù)填充為0
.word? 0xaa55
#魔數(shù) 0xaa55弥雹。
下面是makefile:
TARGET=boot.img
OBJECTS=
CSRC=$(wildcard *.c)
COBJ=$(patsubst %.c,%.o,$(CSRC))
ASRC=$(wildcard *.asm)
AOBJ=$(patsubst %.asm,%.o,$(ASRC))
ALLSRC=$(ASRC) $(CSRC)
ALLOBJECTS=$(AOBJ) $(COBJ)
%.o : %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
%.o : %.asm
$(AS) -o $@ $<
$(patsubst %.img,%.bin,$(TARGET)):$(ALLOBJECTS)
ld -Ttext 0x7c00 -e _start $(ALLOBJECTS)? -o $@
$(TARGET):$(patsubst %.img,%.bin,$(TARGET))
objcopy -R .note -R .comment -S -O binary $< $@
Debug:$(TARGET)
objdump -D -b binary -mi8086 $(TARGET)
cleanDebug:
rm -fr $(ALLOBJECTS) $(TARGET) $(patsubst %.img,%.bin,$(TARGET))
慣例,上圖上真相: