2020年10月19日 星期一

自幹OS筆記 - 02 用Assembly省點事情

因為不可能整個OS全部用 binary 刻出來(是可以  但我不想XD)

所以用點進階的東西來幫助我們 所以接下來要用 x86 架構的 assembly 來寫


因為向後相容性的關係 所以一開始載入 OS 會是 16-bit mode (查了OSDev的 wiki page 說又叫做 Real Mode)

16-bit mode 之後會切換到 32-bit(或是64-bit) mode (應該

總之就是一開始的是16-bit 的 assembly 模式

那如果照著上一篇的邏輯要把它寫成組合語言會長下面這樣

--<boot.asm>-------------------------------------------------------------

loop:

    jmp loop

times 510-($-$$) db 0x00

dw 0xaa55

------------------------------------------------------------------------------

上面的程式碼中比較奇怪的東西是 $ 跟 $$

$ 代表的是當前的位址(address)

$$ 代表的是當前 segment 的初始位址

然後 times 代表的是後面的東西要重複做好幾次

db 是 pseudo-instruction 代表要宣告 one byte 的內容  後面的b = bytes

dw 相對的就是 one word (其中 1 word = 2 bytes)

在這行指令裡面 times 510-($-$$) db 0x00 就是把 jmp 指令後的空間填滿 0x00

填到第 510 bytes 剩下兩個要填上 0xaa55 (識別boot sector)

然後再用 dw 0xaa55 填好最後 2 bytes


寫好之後  組譯的方式為以下指令

    nasm boot.asm -f bin -o boot.bin

組譯完用 xxd 來換成16進位觀看

    xxd boot.bin

--<boot.bin>----------------------------------------------------------------

ebfe 0000 0000 0000 0000 0000 0000 0000

....

0000 0000 0000 0000 0000 0000 0000 55aa

--------------------------------------------------------------------------------

可以看到開頭幾個 bytes 與上一篇手寫的 jmp 不太一樣

翻閱了之後發現

0xeb 其實也是 jmp 只是為 8-bit 模式

所以後面的 0xfe 代表的是 -1

合起來也是 infinite loop 的意思


後記:

寫這個真的讓我很努力學 Assembly

超想努力看懂每個指令的意思

但是資料好難查QAQ  

光一個 $ 就查好久






沒有留言:

張貼留言

Go lang 學習筆記 - 17 Pointers

``` package main import "fmt" func zeroval(n int) {         n = 0 } func zeroptr(n *int) {         *n = 0 } func main() {         ...