04 print Hello through BIOS
我們要利用 BIOS 提供的功能來在螢幕上印出 Hello World
。(如果沒有 BIOS,這個工作會變得很困難,因為有很多種不同的螢幕,每個螢幕的硬體跟 interface 都不相同…)
那我們要怎麼使用 BIOS 的功能呢?
這就要說到 interrupt。
Interrupt
interrupt 是個讓 CPU 暫時停下手上正在做的事、轉去做比較優先的事再回來繼續的機制。interrupt 可以由 software 發出,也可由 hardware device 發出。
每個 interrupt 以一個數字表示,這個數字是 interrupt vector 的 index。interrupt vector 是個由 BIOS 初始化的 table,裡面記錄著指向 interrupt service routine (ISR) 的 address pointer。一個 ISR 就是一段處理特定 interrupt 的 machine code。
那麼,BIOS 在 interrupt vector 中放了一些 ISR,每個 ISR 表示某些部份的功能,例如 0x10
跟螢幕有關、0x13
則跟 disk 有關。
如果為每個 BIOS routine 都指定一個 interrupt,有點浪費,而且 interrupt vector 的大小也是有限的,所以會透過 interrupt 配合 register ax
的值來決定執行哪個 BIOS routine。
印出 Hello
印字的方式是使用 INT 0x10
(video service 的 interrupt)配合 AL
及 AH
register 內的值。register AL
裡放要印的 character,AH
則是放 0x0e
(AL
是 AX
的 lower part、AH
則是 higher part)。AH
放 0x0e
表示要 call「將 AL
內容寫到在 tty mode 下寫到螢幕上」的 function。
在這個例子裡,我們只需要設定一次 AH
為 0x0e
,因為只有一個 process 在 CPU 上跑,AH
的值不會被亂改。
1 | mov ah, 0x0e ; tty mode |
一樣的組譯並執行:
1 | $ nasm -f bin boot_sect_hello.asm -o boot_sect_hello.bin |
會看到像這樣的畫面: