自己動手從零寫桌面作業系統GrapeOS系列教程——15.用匯編向螢幕輸出字元

成宇佳發表於2023-03-16

學習作業系統原理最好的方法是自己寫一個簡單的作業系統。


在上一講中我們介紹了螢幕顯示的原理,本講我們來實戰一下。

一、向螢幕輸出一個字元mbr4.asm

mbr4.asm中的程式碼如下:

;將螢幕第一行的第一個字元顯示為‘G’。
mov ah,0x07 ;黑底白字
mov al,'G'  ;G的ASCII碼是0x47,此時ax的值為0x0747。
mov bx,0xb800
mov es,bx
mov [es:0],ax ;文字模式視訊記憶體地址從0xb8000開始。

stop: ;標號
hlt
jmp stop 

times 510-($-$$) db 0 ;將從上條指令結束到最後2個位元組前的空餘位元組全部置為0。
db 0x55,0xaa

上面程式碼中的註釋比較詳細,結合之前介紹過的內容,大家應該能看懂。下面我們來演示一下。
首先我們回顧一下上節課QEMU中預設顯示的內容:

從上面截圖中可以看到,QEMU中預設顯示的第一行第一個字元是‘S’。
下面我們編譯執行mbr4.asm。

從上面這個截圖可以看到QEMU第一行第一個字元已經變為了字元‘G’,這是我們第一次向螢幕輸出字元。

二、將字元顯示到螢幕的任意位置mbr5.asm

在預設的文字模式中,一屏能顯示25行80列,共2000個字元。每個字元佔用2個視訊記憶體地址,2000個字元共佔用4000個視訊記憶體地址。所以第一屏的視訊記憶體地址範圍是(0xb8000+0)~(0xb8000+4000)。每行顯示80個字元,也就是每行對應160個視訊記憶體地址。在實際使用中,我們需要能將字元輸出到螢幕的任意位置。比如上面的例子中,我們將字元輸出到了QEMU本來就有字元的地方,這樣混在一起不好。我們看到第二行是空白的,我們下面將字元輸出到第二行。
mbr5.asm的程式碼如下:

mov ax,0xb800
mov es,ax
mov ah,0x07
mov al,'G'
mov [es:160],ax ;將字元'G'顯示在螢幕第二行第一個字元的位置

stop:
hlt
jmp stop 

times 510-($-$$) db 0
db 0x55,0xaa

編譯執行截圖如下:

從上面截圖可以看到,我們將字元‘G’顯示在了QEMU第二行第一個字元的位置。

三、向螢幕顯示字串mbr6.asm

mbr6.asm的程式碼如下:

mov ax,0xb800
mov es,ax

;在螢幕第2行顯示字串“GrapeOS"
mov ah,0x07 ;ah中的值一直保持不變
mov al,'G'
mov [es:160],ax
mov al,'r'
mov [es:162],ax ;每個字元對應視訊記憶體中的2個位元組,依次遞增2個位元組。
mov al,'a'
mov [es:164],ax
mov al,'p'
mov [es:166],ax
mov al,'e'
mov [es:168],ax
mov al,'O'
mov [es:170],ax
mov al,'S'
mov [es:172],ax

stop:
hlt
jmp stop 

times 510-($-$$) db 0
db 0x55,0xaa

編譯執行截圖如下:

從上面截圖中可以看到,我成功的在QEMU螢幕第二行顯示出了字串“GrapeOS”。


本講影片版地址:https://www.bilibili.com/video/BV1VY411v7y2/
本教程程式碼和資料:https://gitee.com/jackchengyujia/grapeos-course
GrapeOS作業系統QQ群:643474045

相關文章