自製作業系統 eposide 2

2021-06-29 10:10:25 字數 2678 閱讀 7409

既然我們知道了如何顯示乙個字元,那麼顯示多個字元似乎也不在話下,請看下面**:

mov al,'h'

mov ah,0xe

mov bx,15

int 0x10

mov al,'e'

mov ah,0xe

mov bx,15

int 0x10

mov al,'l'

mov ah,0xe

mov bx,15

int 0x10

mov al,'l'

mov ah,0xe

mov bx,15

int 0x10

mov al,'o'

mov ah,0xe

mov bx,15

int 0x10

fin:

hlt ;讓cpu停止,等待指令

jmp fin ;無限迴圈

resb 0x1fe-$

db 0x55,0xaa

如上所示,似乎這樣就可以顯示乙個hello的字串了,是這樣嗎?以圖為證:

對於fin的解釋:

如果不加這一段,似乎程式也是可以正確執行的,但是最好要加上這段,好讓cpu在沒什麼可做的情況下,不會繼續執行下去,相當於待機狀態。

但是請問,如果要寫一大段的話,那這樣寫可行嗎?我們編寫作業系統豈不是困難多多嗎?其實,如果稍微熟悉一些彙編的人,都知道不要把要顯示的字串儲存在程式裡,而是要儲存到乙個其他的地方迴圈獲取。

下面我隆重介紹乙個暫存器:si暫存器,我們將用它來指示下乙個要獲取的字元在記憶體中的位置,而我們要獲取的資料,將儲存在乙個**段裡面,在記憶體載入磁碟的時候,就會載入這個**段:

message:

db 'hello,world!'

db 0x00

哇塞,組合語言會將這一段**編譯成為什麼呢?不出所料,彙編的結果是:

看到了吧,組合語言會將字串自動進行轉碼,轉換成ascii儲存在程式裡面

既然組合語言將這段**儲存在程式裡面,並且在計算機啟動的時候,被載入到了記憶體裡面,我們就可以在記憶體裡面找到這段**了,當然他們是以010101的形式儲存的,只不過記憶體裡面是8個位8個位為單位的,每8個位元組可以儲存乙個位元組,也就是可以儲存像h這樣的乙個字元了。

那我們如何找到這些字元呢?這是個問題啊,我們不能只儲存不讀取吧。

下面就要發揮si的地方了,請看下面**:

mov si , message + 0x7c00   ;程式的載入位置是記憶體的0x7c00處,因此要加上載入點以前的長度

loop:

mov al,[si] ;將記憶體位址si的位置的記憶體,乙個位元組,載入到al中去

cmp al, 0 ;判斷是否是結束字元(可以自己定)

je fin ;如果相等,則跳轉到結束

add si,1 ;si中的值加1

mov ah,0x0e

mov bx,15

int 0x10

jmp loop ;跳轉回去,繼續執行

fin:

hlt ;讓cpu停止,等待指令

jmp fin ;無限迴圈

message:

db 'hello,world!'

db 0x00

resb 0x1fe-$

db 0x55,0xaa

上面**有一點多,但是主要部分其實還是迴圈,其中 mov al,[si] 就是將si處的記憶體中的資料,載入到al中。

那 mov si,message + 0x7c00 呢?如果寫作 mov si,message 可能還好理解一下,對於標號,其實就是乙個位址,在彙編編譯器看到這個標號的時候,會自動翻譯成為它對於程式一開始的偏移位址,所以寫成 mov si,message 就是將 message的偏移位址寫入si ,那為什麼還要加上 0x7c00呢 ?這是因為,在bios啟動的時候,是要在記憶體中載入很多的驅動的,這些驅動要佔記憶體一部分的地方,而前 0x7c00的位置,都被這些驅動占領了,因此,沒辦法,在作業系統引導的時候,就會把磁碟的0柱面0扇區的512位元組載入到記憶體中,作為啟動區,也就是說,我們其實載入到記憶體中的message的位置,已經偏移了0x7c00個位置的,所以這裡要加回去,這時候,si所指示的位置,就是message在記憶體中的位置了。

下面,需要做迴圈的地方,其實不難

那麼如何跳出迴圈呢:

cmp al, 0    ;判斷是否是結束字元(可以自己定)

je fin ;如果相等,則跳轉到結束

這裡做了很好的解釋,cmp和je指令可以配合使用,這裡表示如果相同,則進行跳轉,語法很簡單,不再多說了。

另外還有其它跳轉指令可以配合,簡單的比如 jne ,指令,表示如果不想等,則跳轉。

你甚至可以這樣寫:

cmp al, 0    ;判斷是否是結束字元(可以自己定)

je fin ;如果相等,則跳轉到結束

je fin ;如果不相等,則跳轉到結束

這就和無條件跳轉一樣了。哈哈哈哈。

自製作業系統 (2)

接上篇,檔案跳轉到了entry.s裡面,這是kernel的入口。首先面臨這麼乙個問題,kernel被載入到了什麼地方?回想上篇elf檔案的載入機制,以及objdump裡列印出的kernel資訊,可以看到,kernel的 段 text段 被載入到了0x100000的位置,也就是1m的位置,所以記憶體布...

自製作業系統 二

組合語言學習與makefile入門 2.helloos.nas程式核心部分。jmp指令 jump,跳轉。相當於c中的goto。mov指令 move,移動。理解mov指令就理解彙編一大半。指賦值的功能 把乙個東西移走了,他原來占用的位置不會空出 3.cpu的一種儲存電路 暫存器,相當於變數的功能。以下...

自製作業系統(二)

現在呢,大致流程寫在下面 首先,編寫彙編 檔名為myos.asm,所有 大致如下 下面是標準fat12格式軟盤專用 db 0xeb,0x4e,0x90 db myos ipl 啟動區名稱,必須8位元組 dw 512 每個扇區必須為512位元組 db 1 蔟必須為1個扇區 dw 1 fat的起始位置必...