跟我一起写操作系统

    返回首页    发表留言
本文作者:李德强
          第五节 显示Hello World
 
 

        在前面我们分别采用软盘镜像和光盘镜像使我们的操作系统程序boot.bin通过软驱和光驱将计算机引导启动。但是这个简单的不能再简的操作系统没有任何实际内容。下面我们就要一起来学习,如何让我们的操作系统程序在屏幕上显示一串字符:“Hello World!”

        内存地址中0xb8000 – 0xbffff共32KB的空间,这是80 * 25彩色字符模式的显示缓冲区。向这个地址空间中写入数据,写入的内容将立即出现在显示器上。在80 * 25彩色字符模式下,显示器可以显示25行,每行80个字符,每个字符可以有256种属性,包括背景色、前景色、闪烁、高亮等互相组合。这样的话对于一个可显字符,ASCII码占用1个字节,属性占用1个字节,所以如果要显示一个字符就需要2个字节的内存空间。

        从0xb8000开始,偏移0x0 – 0x9f对应显示器上第1行;偏移0xa0 – 0x13f对应显示器上的第2行;偏移0x140 – 0x1df对应的显示器上的第3行,以此类推。在一行中,一个字符占两个字节,高位字节存储属性,低位字节存储ASCII码。

        字符属性格式如下:

bit位       7        6        5        4        3        2        1        0
           BL        R        G        B        I        R        G        B
           闪烁              背景               高亮               前景

        比如:

红底绿字,属性字节为:01000010B = 0x42;
红底闪烁绿字,属性字节为:11000010B = 0xc2;
红底高亮绿字,属性字节为:01001010B = 0x4a;
黑底白字,属性字节为:00000111B = 0x07;
白底蓝字,属性字节为:01110001B = 0x71。

        现在我们要在显示器上显示一串字符“Hello World!”这个字符串就是普通的黑底白字,所以它每个字节属性都为0x07,修改boot.S文件并写入程序如下:

//开始
_start:
//将es设为0xb800。
movw        $0xb800,   %ax
movw        %ax,       %es

//将ds设为0x07c0。
movw        $0x07c0,   %ax
movw        %ax,       %ds

//将si指向“Hello World!”字符串地址。
movw        $_str,     %si

//清空di。
xorw        %di,       %di

_copy:
//判断字符串结束符‘\0’
cmp         $0,        %ds:(%si)

//如果是字符串结束符\0则直接跳出循环。
je      _loop

//拷贝字符的ASCII码到al。
movb %ds:(%si),        %al

//设定字符显示前景色和背景色,黑底白字。
movb $0x07,            %ah
movw %ax,              %es:(%di)

//si加1,ds:si将指向下一个字符的位置。
addw $1, %si

//di加2,es:di指向下一个显示字符的位置(一个可显示字符占两个字节)。
addw $2, %di

jmp _copy
_loop:
jmp _loop
_str:
.string "Hello World!\0"

        定义“Hello World!”字符串,并以‘\0’为结束符。

        执行make all编译工程,并重新启动lidqos虚拟机,查看运行结果,已经在屏幕上显示了非常亲切的字符串“Hello World!”如下图:



 

        源代码的下载地址为:

https          https://github.com/magicworldos/lidqos.git
git            git@github.com:magicworldos/lidqos.git
subverion      https://github.com/magicworldos/lidqos
branch         v0.3

 

    返回首页    返回顶部
#1楼  匿名  于 2021年01月22日13:34:00 发表
 
一开始没注意,以为运行不成功. 可以在_copy:之前加个清屏动作,方便调试

clear:

xorw %bx, %bx

_clear_loop:

// 清屏,80行*25字符*2(一个字符2字节表示)=4000

cmp $4000, %bx

je _copy

// 拷贝字符到al, 空格是32

movb $32, %al

// 设定字符显示前景色和背景色,黑底灰字

movb $0x07, %ah

movw %ax, %es:(%bx)

addw $2, %bx

jmp _clear_loop

  看不清?点击刷新

 

  Copyright © 2015-2023 问渠网 辽ICP备15013245号