歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux內核

Linux內核系列—操作系統開發之HelloWorld

		org 07c00h	    ;偽指令,告訴編譯器程序會被加載到7c00處

		mov ax, cs
		mov ds, ax
		mov es, ax
		call DispStr	     ;調用顯示字符串例程
		jmp $			;無限循環
DispStr:
		mov ax, BootMessage
		mov bp, ax		;ES:BP=字符串地址
		mov cx, 16		;CX=字符串長度

		mov ax, 01301h		;AH=13,AL=01h
		mov bx, 000ch		;頁號為0(BH=0)黑底紅字(BL=0Ch,高亮)
		mov dl, 0
		int 10h			;10h號中斷
		ret	                ;pop IP
BootMessage:	db "Hello, OS world!"
times 510-($-$$)db 0	         ;填充剩下的空間,使生成的二進制代碼恰好為512字節
dw	0xaa55				;結束標志
        

以上是個非常簡單的操作系統helloworld源碼,用bochs加載後如下圖(bochs是個虛擬機,模擬操作系統加載),顯示了紅色的Hello,OS world,實際上是系統加載起來的樣子:

源碼解析:

1.org 07c00h和dw 0xaa55和times 510-($-$$) db 0

當計算機電源打開,會先進行加電自檢(POST),然後尋找啟動盤,如果是選擇從軟盤啟動,計算機會檢查軟盤的0面0磁道1扇區,如果發現它以0xaa55結束,則BIOS認為它是一個引導扇區。一個正確的引導扇區除了以0xaa55結束之外,還應該包含一段512字節的執行碼。一旦BIOS發現了引導扇區,就會將這512字節的內容裝載到內存地址0000:7c00處,然後跳轉到0000:7c00處將控制權徹底交給這段引導代碼。

org 07c00h就是告訴編譯器,這段代碼是要被加載到這個地址的。所以BootMessage的偏移地址是相對於07c00h處開始的。BootMessage實際上也是一個地址,不是相對量

2.mov ax, cs、mov ds, ax、mov es, ax

讓ds和es指向當前代碼段。以便在以後進行數據操作的時候能定位到正確的位置。

3.call DispStr

調用顯示字符串的函數,在NASM中,任何不被[]括起來的標簽或變量名都被認為是地址,如果是訪問標簽中的內容則必須使用[]。所以mov ax, BootMessage會把"Hello,OS world!"這個字符串的首地址傳給寄存器ax。然後mov bp, ax賦給bp,如果沒寫org指令,則BootMessage編譯的時候就是相對於本程序加載到地址0的偏移地址,但是這裡是相對於07c00h為基址的偏移地址,所以這裡顯示了org的作用。

4.int 10h

10H中斷是由BIOS對顯示器和屏幕所提供的服務程序。使用int 10h服務程序時,必須先指定ah寄存器。

功能13h:

功能描述:在Teletype模式下顯示字符串
入口參數:AH=13H
BH=頁碼
BL=屬性(若AL=00H或 01H)
CX=顯示字符串長度
(DH、DL)=坐標(行、列)

ES:BP=顯示字符串的地址
AL=顯示輸出方式
0—— 字符串中只含顯示字符,其顯示屬性在BL中。顯示後,光標位置不變
1——字符串中只含顯示字符,其顯示屬性在BL中。顯示後,光標位置改變
2 ——字符串中含顯示字符和顯示屬性。顯示後,光標位置不變
3——字符串中含顯示字符和顯示屬性。顯示後,光標位置改變
出口參數:無

5.$和$$

$-$$表示本行距離程序開始處的相對距離。times 510-($-$$) db 0表示將0這個字節重復510-($-$$)遍,也就是在剩下的空間中不停地填充0,直到程序有510字節為止。這樣,加上結束標志0xaa55占用的2字節,恰好是512字節。

Copyright © Linux教程網 All Rights Reserved