经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » 汇编语言 » 查看文章
自己动手从零写桌面操作系统GrapeOS系列教程——17.用汇编语言清空屏幕
来源:cnblogs  作者:成宇佳  时间:2023/3/20 8:43:28  对本文有异议

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


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

一、清空屏幕

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

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

编译运行截图如下:

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

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

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

  1. ;定义常量(作用和C语言中的#define一样)
  2. VIDEO_CHAR_MAX_COUNT equ 2000 ;默认屏幕最多显示字符数。
  3. org 0x7c00 ;如果没有该行将无法正确打印要显示的字符串
  4. ;初始化段寄存器
  5. mov ax,cs
  6. mov ds,ax ;ds指向与cs相同的段
  7. mov ax,0xb800
  8. mov es,ax ;本程序中es专用于指向显存段
  9. ;清屏
  10. call func_clear_screen
  11. ;打印字符串
  12. mov si,string1
  13. mov di,0 ;在屏幕第1行显示
  14. call func_print_string
  15. stop:
  16. hlt
  17. jmp stop
  18. ;清屏函数(将屏幕写满空格就实现了清屏)
  19. ;输入参数:无。
  20. ;输出参数:无。
  21. func_clear_screen:
  22. mov ah,0x00 ;黑底黑字
  23. mov al,' ' ;空格
  24. mov cx,VIDEO_CHAR_MAX_COUNT ;循环控制
  25. .start_blank:
  26. mov bx,cx ;以下3行表示bx=(cx-1)*2
  27. dec bx
  28. shl bx,1
  29. mov [es:bx],ax ;[es:bx]表示字符对应的显存地址(从屏幕右下角往前清屏)
  30. loop .start_blank
  31. ret
  32. ;打印字符串函数。
  33. ;输入参数:ds:sidi
  34. ;输出参数:无。
  35. ;ds:si 表示字符串起始地址,以0为结束符。
  36. ;di 表示字符串在屏幕上显示的起始位置(0~1999)。
  37. func_print_string:
  38. mov ah,0x07 ;ah表示字符属性,0x07表示黑底白字。
  39. shl di,1 ;乘2(屏幕上每个字符对应2个显存字节)。
  40. .start_char: ;以点开头的标号为局部标号,完整形式是 func_print_string.start_char,但在同一个全局标号func_print_string内部不需要写完整形式。
  41. mov al,[si]
  42. cmp al,0
  43. jz .end_print
  44. mov [es:di],ax ;将字符和属性放到对应的显存中。
  45. inc si
  46. add di,2
  47. jmp .start_char
  48. .end_print:
  49. ret
  50. string1:db "Hello GrapeOS!",0
  51. times 510-($-$$) db 0
  52. 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

原文链接:https://www.cnblogs.com/chengyujia/p/17229428.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号