《自己動手寫作業系統》讀後感 http://write.blog.csdn.net/postedit/7060032
在本章,我想跟大家分享一下自己的迷惑,主要是對這段程式理解。
org 07C00h ; 告訴編譯器程式載入到07C00處
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
BootMessage: db "Hello,OS world!"
times 510-($-$$) db 0 ; 填充剩下的空間,使產生的二進位代碼恰好為512位元組
dw 0xaa55 ; 結束標誌
1、 org 07C00h
org偽指令
格式:ORG 數值運算式
其中,ORG(origin)是作業碼,不可省略。運算式給出位移地址值,即ORG語句後的指令或資料以運算式給出的值作為起始的位移地址。運算式必須是一個可計算得到的正整數,數值範圍在0~65 535之間。
ORG偽指令用來指出其後的程式段或資料區塊存放的起始地址的位移量。組譯工具彙編時把語句中運算式的值作為起始地址,連續存放ORG語句之後的程式和資料,直到出現一個新的ORG指令。若省略ORG語句,則從本段起始地址開始連續存放。
在大多數情況下,不需要用ORG語句設定位置指標。由於段定義語句是段的起點,它的位移地址為0000H,以後每分配一個位元組,位置指標自動加1,所以每條指令都有確定的位移地址。只有程式要求改變這個位置指標時,才需要安排ORG語句。通常ORG語句可以出現在程式中任何位置上。
下列變數定義,並且變數word1的位移量為0
word1 DW 1234h
byte1 DB 56h
word2 DW abcdh
org 0001h
byte2 DB ?
word3 DW ?
byte3 DB ?
故如所示:
我們知道編譯器本身在彙編時對指令的地址計算是相對位址,而對於開機磁區,是按絕對位址執行,那麼對於用相對位址編譯的執行碼就要換算成絕對位址。一般而言,“真實開始執行的開機磁區”都會固定裝載到07C00h處。
由於編譯器在編譯時間的地址是從第一行開始用0000h開始相對計算的,而且我們要寫的是“開機磁區”程式,所以我們要將下面的代碼載入到地址07C00h處,所以我們需要org 07C00h,通過該偽指令,將代碼和資料載入到07C00h地址。
2、jmp $
$被稱為當前位置計數器
在組譯工具對來源程式進行彙編的過程中,使用地址計數器來保證當前正在彙編的指令地址。地址計數器值可用“$”來表示,組合語言也允許使用者直接用“$”來引用地址計數器的當前值,因此,ORG $+5可表示從當前地址開始跳過5個位元組儲存單元,在指令和偽指令中,也可直接用“$”表示地址計數器的當前值。
故jmp $進入了一個無限迴圈。
3、int 10h
int 10號中斷
int 10H 是由BIOS 對螢幕及顯示器所提供的服務程式。使用 INT 10H 中斷服務程式時,先指定 AH 寄存器為下表編號其中之一,該編號表示欲調用的功用,而其他寄存器的詳細說明,參考表後文字,當一切設定好之後再調用 int 10H。
在這裡我們只詳細講解本程式中的10號中斷。由於ah=13,故調用編號為13的功能:即顯示字串。其中ES:BP=串地址,CX=串長度 ,AH=13,當AL=01h時,游標會跟隨顯示移動。BH為頁號,BH=0表示頁號為0,BL=0CH,表示屬性,即黑底紅字高亮。
因此在調用10號中斷之前,無非就是對各個寄存器進行初始化。
關於10號中斷的其他資訊,請參考
http://blog.csdn.net/yes_life/article/details/6778834
4、times 510-($-$$) db 0
times:重複指令或資料
times首碼引起指令被彙編多次。其中$$表示是該程式的初始程式碼片段的地址,故該指令將會被執行510-($-$$)次。也就是用0來填充剩下的空間,達到510位元組。