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

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


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

一、向屏幕輸出一個字符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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章