• 自己动手从零写桌面操作系统GrapeOS系列教程——17.用汇编语言清空屏幕


    学习操作系统原理最好的方法是自己写一个简单的操作系统。


    在QEMU中会默认输出一些字符,有时候会干扰我们自己输出的字符。一个比较好的办法是向将屏幕清空,再输出我们想要输出的字符。下面就来学习如何清空屏幕。

    一、清空屏幕

    其实清空屏幕的原理很简单,就是将屏幕写满空格就行了。
    下面来实战。mbr8.asm代码如下:

    ;定义常量(作用和C语言中的#define一样)
    VIDEO_CHAR_MAX_COUNT equ 2000 ;默认屏幕最多显示字符数。
    
    org 0x7c00
    
    ;初始化段寄存器
    mov ax,0xb800
    mov es,ax ;本程序中es专用于指向显存段
    
    ;清屏
    call func_clear_screen
    
    stop:
    hlt
    jmp stop 
    
    ;清屏函数(将屏幕写满空格就实现了清屏)
    ;输入参数:无。
    ;输出参数:无。
    func_clear_screen:
    mov ah,0x00 ;黑底黑字
    mov al,' '  ;空格
    mov cx,VIDEO_CHAR_MAX_COUNT ;循环控制
    .start_blank:
    mov bx,cx ;以下3行表示bx=(cx-1)*2 
    dec bx
    shl bx,1
    mov [es:bx],ax ;[es:bx]表示字符对应的显存地址(从屏幕右下角往前清屏)
    loop .start_blank
    ret
    
    times 510-($-$$) db 0
    db 0x55,0xaa
    

    编译运行截图如下:

    从上面QEMU截图可以看到,之前QEMU默认输出的字符已经没有了,屏幕清空的很干净。

    二、在清空的屏幕上输出字符串

    一般我们都是先清空屏幕,再输出自己想要输出的字符串。
    下面我们来看mbr9.asm的代码:

    ;定义常量(作用和C语言中的#define一样)
    VIDEO_CHAR_MAX_COUNT equ 2000 ;默认屏幕最多显示字符数。
    
    org 0x7c00 ;如果没有该行将无法正确打印要显示的字符串
    
    ;初始化段寄存器
    mov ax,cs
    mov ds,ax ;ds指向与cs相同的段
    mov ax,0xb800
    mov es,ax ;本程序中es专用于指向显存段
    
    ;清屏
    call func_clear_screen
    
    ;打印字符串
    mov si,string1
    mov di,0 ;在屏幕第1行显示
    call func_print_string
    
    stop:
    hlt
    jmp stop 
    
    ;清屏函数(将屏幕写满空格就实现了清屏)
    ;输入参数:无。
    ;输出参数:无。
    func_clear_screen:
    mov ah,0x00 ;黑底黑字
    mov al,' '  ;空格
    mov cx,VIDEO_CHAR_MAX_COUNT ;循环控制
    .start_blank:
    mov bx,cx ;以下3行表示bx=(cx-1)*2 
    dec bx
    shl bx,1
    mov [es:bx],ax ;[es:bx]表示字符对应的显存地址(从屏幕右下角往前清屏)
    loop .start_blank
    ret
    
    ;打印字符串函数。
    ;输入参数:ds:si,di。
    ;输出参数:无。
    ;ds:si 表示字符串起始地址,以0为结束符。
    ;di 表示字符串在屏幕上显示的起始位置(0~1999)。
    func_print_string:
    mov ah,0x07 ;ah表示字符属性,0x07表示黑底白字。
    shl di,1 ;乘2(屏幕上每个字符对应2个显存字节)。
    .start_char: ;以点开头的标号为局部标号,完整形式是 func_print_string.start_char,但在同一个全局标号func_print_string内部不需要写完整形式。
    mov al,[si]
    cmp al,0
    jz .end_print
    mov [es:di],ax ;将字符和属性放到对应的显存中。
    inc si
    add di,2
    jmp .start_char
    .end_print:
    ret
    
    string1:db "Hello GrapeOS!",0
    
    times 510-($-$$) db 0
    db 0x55,0xaa
    

    mbr9.asm其实就是将mbr8.asm和mbr7.asm合并了一下。
    下面来看编译运行截图:

    从上面的QEMU截图中可以看到,我们在清空的屏幕上第一行显示了字符串“Hello GrapeOS!”,这就是我们想要的效果。


    本讲视频版地址:https://www.bilibili.com/video/BV1DD4y137ET/
    本教程代码和资料:https://gitee.com/jackchengyujia/grapeos-course
    GrapeOS操作系统QQ群:643474045

  • 相关阅读:
    MySQL备份与恢复
    计算机毕业设计ssm宠物商店信息展示与服务订购系统7q5ic系统+程序+源码+lw+远程部署
    计算机网络最后复习
    Bridge 2024 新版本 Bridge 2024 mac软件特色和功能
    【简单的自动曝光】python实现-附ChatGPT解析
    神经网络学习的基本原理
    运营-20.产品社区化和内容化
    linux入门---信号的操作
    Spring(五)- Bean 实例化的基本流程
    Vue3+TS+ECharts5实现中国地图数据信息显示
  • 原文地址:https://www.cnblogs.com/chengyujia/p/17229428.html