自己动手从零写桌面操作系统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

posted @ 2023-03-16 11:57  成宇佳  阅读(476)  评论(0编辑  收藏  举报