hello world

? ? ? ? 在開始之前講個有意思的笑話。某日,一程序猿退休在家,閑來無事想學習書法。開始時候左思右想,不知如何下筆,突然靈光一閃提筆寫下了幾個大字,定睛一看“hello world”。

所以這里,國際慣例我這里也是按照hello world開始。OK。

? ? ? ? 編譯連接完成了以后,這個代碼必須是在MBR上大小為512個字節并且必須要以0xAA55結束,這里不要問我為啥子。我也不曉得,估計這個需要問IBM的PC開發的工程師為啥要這樣定。開機自檢完成以后PC會將MBR上的前512個字節的程序,讀取到內存0x0000:0x07c0處,然后跳轉到這個地址執行,這里執行的就是我們的程序。這個Hello world 程序相當簡單,調用0x10號中斷,完成清屏和顯示“terrycheng”。這個程序我是在ubuntu下面實際能夠編譯完成,在bochsrc能夠運行的。嘎嘎。

詳細代碼:boot.asm

.section .text

.global _start

.code16

#這個也很重要,因為這里實際PC還是在實模式下,也就說為16位的機器,所以這里的數據都是要16位的。

.extern main

_start:

movw %cx, %ax

movw %ax, %ds

movw %ax, %es

#上面3行的作用是設置數據段寄存器,這個時候PC跳轉到了0x0000:0x07c0處,所以CX寄存器地址為0x0000,然而其他的數據段確不是這個地址。

#所以需要設置和代碼段一樣否則后面的terrycheng這個數據,是找不到的。

call ClearScreen

#調用后面的ClearScreen函數,完成清屏。

movw $msgstr, %bp

movw $10,? ? %cx

call Display

#調用0x10號中斷,顯示terrycheng

1:

jmp 1b

#不解釋,死循環。

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的數據位置。

len:

.int? ? . - msgstr

#計算terrycheng的長度

.org? ? 0x1fe,? 0x00

#進行填充,之前我說過的MBR大小必須為512個字節,所以這里就把后面的數據填充為0

.word? 0xaa55

#魔數 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))

慣例,上圖上真相:

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容