注:以下程序系原创,使用AT&T格式汇编来调用BIOS 0x10中断,如有错误,欢迎指正。表达能力较差,写的不好,但若能帮助一二访客,幸甚。

使用BIOS 显示服务(Video Service)--INT 10H,下面主要探究字符显示模式。

BIOS中断在保护模式下是不能用的,故不能在Linux中测试,所以写了个简单的boot loader,并在虚拟机中运行程序。

1.以电传的方式写入字符串(AH=0x13)

[cpp] view plaincopyprint?
  1. ------------------------------------------------------------------
  2. INT 0x10功能0x13
  3. --------------------------------------------------------------
  4. 描述:
  5. 以电传打字机的方式显示字符串
  6. 接受参数:
  7. AH          0x13
  8. AL          显示模式
  9. BH          视频页
  10. BL          属性值(如果AL=0x00或0x01)
  11. CX          字符串的长度
  12. DH,DL       屏幕上显示起始位置的行、列值
  13. ES:BP       字符串的段:偏移地址
  14. 返回值:
  15. 显示模式(AL):
  16. 0x00:字符串只包含字符码,显示之后不更新光标位置,属性值在BL中
  17. 0x01:字符串只包含字符码,显示之后更新光标位置,属性值在BL中
  18. 0x02:字符串包含字符码及属性值,显示之后不更新光标位置
  19. 0x03:字符串包含字符码及属性值,显示之后更新光标位置
  20. -------------------------------------------------------------------

示例:

[cpp] view plaincopyprint?
  1. # A bootsect, which print a string by BIOS interrupt video services(int 0x10)
  2. .section .text
  3. .global _start
  4. .code16
  5. _start:
  6. movw    %cx,    %ax
  7. movw    %ax,    %ds
  8. movw    %ax,    %es
  9. movw    $msgstr,%bp
  10. movw    len,    %cx
  11. movb    $0x05,  %dh
  12. movb    $0x08,  %dl
  13. movb    $0x01,  %al
  14. movb    $0x13,  %ah
  15. movb    $0x01,  %bl
  16. movb    $0x00,  %bh
  17. int     $0x10
  18. 1:
  19. jmp     1b
  20. msgstr:
  21. .asciz  "Hello babyos(print by BIOS int 0x10:0x13, mode 0x01)!"
  22. len:
  23. .int    . - msgstr
  24. .org    0x1fe,  0x90
  25. .word   0xaa55
  26. makefile:
  27. all: boot.img
  28. boot.o: boot.s
  29. as -o $@ $<
  30. boot: boot.o
  31. ld --oformat binary -N -Ttext 0x7c00 -o $@ $<
  32. boot.img: boot
  33. dd if=boot of=boot.img bs=512 count=1
  34. clean:
  35. rm ./boot ./boot.img ./boot.o

运行:

2.通过功能号0x09探究色彩控制

上面的显示为什么是红色呢?我们可以通过实验来看一下颜色控制。

[cpp] view plaincopyprint?
  1. ------------------------------------------------------------------------
  2. INT 0x10功能0x09
  3. -------------------------------------------------------------------
  4. 描述:
  5. 显示字符并设置其属性
  6. 接受参数:
  7. AH          0x09
  8. AL          字符的ASCII码
  9. BH          视频页
  10. BL          属性值
  11. CX          重复次数
  12. 返回值:
  13. 注意:
  14. 在显示字符之后并不前进光标。在文本和图形模式下均可调用该功能
  15. 显示完字符后,如果还要继续显示字符,必须调用INT 0x10功能0x02前进光标
  16. -------------------------------------------------------------------------
  17. ------------------------------------------------------------------------
  18. INT 0x10功能0x02
  19. -------------------------------------------------------------------
  20. 描述:
  21. 把光标定位在选定视频页的特定行列位置
  22. 接受参数:
  23. AH          0x02
  24. DH,DL       行、列值
  25. BH          视频页
  26. 返回值:
  27. 注意:
  28. 在80x25模式下,DH范围0~24,DL范围0~79
  29. -------------------------------------------------------------------------

示例:

实现一个从第4行~7行,第8列~71列,显示‘A’~‘Z’的程序,共显示256个字符,使用BL(0~255)

C 伪代码:

[cpp] view plaincopyprint?
  1. cx = 0x04;
  2. bh = 0x00;
  3. dh = 0x04;
  4. dl = 0x08;
  5. al = 'A';
  6. for (bl = 0; bl < 256; bl++)
  7. {
  8. print_char();
  9. al++;
  10. if (al == 'Z')
  11. al = 'A';
  12. dl++;
  13. if (dl == 72)
  14. {
  15. dh++;
  16. dl = 4;
  17. }
  18. set_cursor();
  19. }

汇编代码:

[cpp] view plaincopyprint?
  1. # A bootsect, which print a colorful chars by BIOS INT 0x10, 0x09
  2. .section .text
  3. .global _start
  4. .code16
  5. _start:
  6. movw    %cx,    %ax
  7. movw    %ax,    %ds
  8. movw    %ax,    %es
  9. movw    $0x01,  %cx     # 字符显示重复次数
  10. movb    $0x00,  %bh     # 视频页
  11. movb    $0x04,  %dh     # 显示起始行
  12. movb    $0x08,  %dl     # 显示起始列
  13. movb    $'A',   %al     # 显示字符
  14. movb    $0x00,  %bl     # 属性值
  15. 1:
  16. call    print_char
  17. incb    %al
  18. cmpb    $'Z',   %al
  19. jne     2f
  20. movb    $'A',   %al
  21. 2:
  22. incb    %dl
  23. cmpb    $72,    %dl
  24. jne     3f
  25. movb    $8,     %dl
  26. incb    %dh
  27. 3:
  28. call    set_cursor
  29. incb    %bl
  30. cmp     $256,   %bl
  31. jne     1b
  32. jmp     1f
  33. print_char:
  34. movb    $0x09,  %ah
  35. int     $0x10
  36. ret
  37. set_cursor:
  38. movb    $0x02,  %ah
  39. int     $0x10
  40. ret
  41. 1:
  42. jmp     1b
  43. .org    0x1fe,  0x90
  44. .word   0xaa55

结果:

可以显式地验证色彩控制BL:

[cpp] view plaincopyprint?
  1. 7       6       5       4       3       2       1       0
  2. I       R       G       B       I       R       G       B
  3. 闪烁    R     G       B       I       R       G       B

如上图所示,7~4位为背景色,I表示高亮,RGB表示红绿蓝,若显卡支持闪烁,则位7表示是否闪烁。
色彩混合:

[cpp] view plaincopyprint?
  1. -----------------------------------------------------------
  2. 混合的三种基色     不开启亮度位      开启亮度位
  3. -------------------------------------------------------
  4. 红+绿+蓝           浅灰              白色
  5. 绿+蓝             青色              浅青
  6. 红+蓝             洋红              浅洋红
  7. 红+绿             棕色              黄色
  8. 无色彩             黑色              暗灰
  9. -----------------------------------------------------------

3.清屏

可以发现屏幕上有许多Bochs的打印信息,看着不爽,想办法去掉它们。

利用0x06号功能,上卷全部行,则可清屏。

-----------------------------------------------------------
INT 0x10 功能0x06
------------------------------------------------------
描述:
上卷窗口
参数:
AH 6
AL 上卷的行数(0表示全部)
BH 空白区域的视频属性
CH,CL 窗口左上角的行列位置
DH,DL 窗口右下角的行列位置
返回值:

------------------------------------------------------------
示例:

[cpp] view plaincopyprint?
  1. # A bootsect, which print a colorful chars by BIOS INT 0x10, 0x09
  2. .section .text
  3. .global _start
  4. .code16
  5. _start:
  6. movw    %cx,    %ax
  7. movw    %ax,    %ds
  8. movw    %ax,    %es
  9. call    clear_screen    # 清屏
  10. movw    $0x01,  %cx     # 字符显示重复次数
  11. movb    $0x00,  %bh     # 视频页
  12. movb    $0x04,  %dh     # 显示起始行
  13. movb    $0x08,  %dl     # 显示起始列
  14. movb    $'A',   %al     # 显示字符
  15. movb    $0x00,  %bl     # 属性值
  16. 1:
  17. call    print_char      # 打印字符
  18. incb    %al             # 下一个字符
  19. cmpb    $'Z',   %al     # 是否该重新从‘A’开始
  20. jne     2f
  21. movb    $'A',   %al
  22. 2:
  23. incb    %dl             # 下一个位置
  24. cmpb    $72,    %dl     # 是否到下一行
  25. jne     3f
  26. movb    $8,     %dl
  27. incb    %dh
  28. 3:
  29. call    set_cursor      # 设置光标位置
  30. incb    %bl             # 下一种属性
  31. cmp     $0,     %bl     # 是否256种属性用完
  32. jne     1b
  33. jmp     1f              # 结束
  34. clear_screen:               # 清屏函数
  35. movb    $0x06,  %ah     # 功能号0x06
  36. movb    $0,     %al     # 上卷全部行,即清屏
  37. movb    $0,     %ch     # 左上角行
  38. movb    $0,     %ch     # 左上角列
  39. movb    $24,    %dh     # 右下角行
  40. movb    $79,    %dl     # 右下角列
  41. movb    $0x07,  %bh     # 空白区域属性
  42. int     $0x10
  43. ret
  44. print_char:
  45. movb    $0x09,  %ah     # 功能号0x09
  46. int     $0x10
  47. ret
  48. set_cursor:
  49. movb    $0x02,  %ah     # 功能号0x02
  50. int     $0x10
  51. ret
  52. 1:
  53. jmp     1b
  54. .org    0x1fe,  0x90
  55. .word   0xaa55

结果:

4.直接写显存绘制字符串:

示例:

[cpp] view plaincopyprint?
  1. #---------------------------------------------------------------
  2. # 直接写显存显示一些文字函数:
  3. #   显示计算机当前工作的显示模式
  4. draw_some_text:
  5. # 设置ES,DS的值
  6. movw    $VIDEO_SEG_TEXT,%ax
  7. movw    %ax,            %es
  8. xorw    %ax,            %ax
  9. movw    %ax,            %ds
  10. # 计算字符显示位置的显存地址(目标地址)
  11. movw    $((80*TEXT_ROW+TEXT_COL) * 2),  %di
  12. # 源字符串地址
  13. leaw    msgstr,         %si
  14. movb    $TEXT_COLOR,    %al     # 属性值(颜色)
  15. movw    len,            %cx     # 显示的字符个数
  16. draw_a_char:
  17. movsb
  18. stosb
  19. loop    draw_a_char
  20. ret

利用BIOS 中断INT 0x10显示字符和字符串相关推荐

  1. 3. 51——LCD1602显示 字符、字符串、数字

    51--LCD1602显示 字符.字符串.数字 LCD1602简介 LCD1602相关引脚 LCD1602写命令.写数据相关操作图 写指令 代码 写数据 代码 LCD1602显示程序步骤及如何初始化 ...

  2. PIC单片机利用视觉暂留现象显示字符

    Persistance of Vision (PoV), 即视觉暂留现象, 人眼在观察景物时,光信号传人大脑神经,需经过一段短暂的时间,光的作用结束后,视觉形象并不立即消失,这种残留的视觉称" ...

  3. 一步步编写操作系统 34 内核利用bios中断获取物理内存大小

    接上文,另一个获取内存容量的方法是bios 0x15中断的子功能0xE801. 此方法虽然简单,但功能也不强大,最大只能识别4G内存,不过这对咱们32位地址总线足够了.稍微有点不便的是,此方法检测到的 ...

  4. 一步步编写操作系统 33 利用bios中断0x15子功能0xe820获取内存

    咱们先介绍0xE820子功能,这是最灵活的内存获取方式. bios中断 0x15的子功能0xE820能够获取系统的内存布局,由于系统内存各部分的类型属性不同,bios就按照类型属性来划分这片系统内存, ...

  5. 51单片机LCD1602液晶屏显示字符,字符串,(有)无符号整数,十六进制数,二进制数等

    1.前言 LCD1602液晶显示器是广泛使用的一种字符型液晶显示模块.液晶显示模块具有体积小.功耗低.显示内容丰富.超薄轻巧等优点,在嵌入式应用系统中得到越来越广泛的应用,这讲中向大家介绍的LCD16 ...

  6. babyos (三)——利用BIOS INT 0x13读取软盘

    注:以下程序为原创,若发现任何BUG,欢迎指正:若有问题,欢迎交流:权利归原作者所有,若转载,请注明出处:若能有益于一二访客,幸甚. 昨天学习了VGA显示的一些东西,今天准备学习一下读取软盘的知识. ...

  7. BIOS中断大全:“INT 10H ~ INT 1AH”

    BIOS中断: 1.显示服务(Video Service--INT 10H) 00H -设置显示器模式 01H -设置光标形状 02H -设置光标位置 03H -读取光标信息 04H -读取光笔位置 ...

  8. cmos 和 bios中断大全

    1,cmos简介.    cmos是主板上一块可读写的RAM芯片.用途:主要用来保存当前系统的硬件配置和操作人员对某些参数的设定.cmos芯片是由一块纽扣电池供电.因此在关机状态内部信息也不会丢失. ...

  9. STM32 OLED显示字符汉字

    本文代码使用 HAL 库. 文章目录 前言 一. OLED 接线: 二.点阵: 三.写数据,命令函数 四.显示字符,字符串: 总结 前言 OLED 屏幕是一种高对比度.高亮度.低功耗.灵活可弯曲的显示 ...

最新文章

  1. Java集合,ConcurrentHashMap底层实现和原理(常用于并发编程)
  2. VS调试python中的DLL
  3. 广义逆高斯分布及推广(To be continued)
  4. EasyUI学习总结(一)——EasyUI入门
  5. java main是标识符吗_main方法的认识 、通配符、java的注释、java的符(标识符)【Java基础】...
  6. oracle 增量_【干货分享】DMETL中的增量抽取初识
  7. Js 获取当前页面的高度
  8. 沈抚示范区·“华为云杯”2021全国AI大赛圆满落幕
  9. 女生适合当程序员吗?
  10. Windows下用C语言连接Mysql注意问题
  11. sqlserver数据库置疑处理
  12. Windows 7 修改系统临时文件夹
  13. Strut2的工作流程
  14. imovie导入媒体没有声音的解决办法
  15. 新应用——信息化财务管理,一站式满足多个需求
  16. matlab成功安装libsvm后,运行程序仍报错“svmtrain has been removed”解决方法记录
  17. vue 拖拽功能样式优化
  18. Mac电脑 绑定阿里云企业邮箱
  19. 基于Redis的BloomFilter实现
  20. 《游戏改变世界》读后感 一 (懊悔?and我眼中的好游戏)

热门文章

  1. UVA11384正整数序列(把123..变成0的最小步数)
  2. 【Linux 内核】进程管理 ( Linux 内核中的进程状态 | TASK_RUNNING | TASK_INTERRUPTIBLE | __TASK_STOPPED | EXIT_ZOMBIE )
  3. 【Linux 内核】编译 Linux 内核 ② ( 解压内核源码 | 查询当前 Linux 内核版本号 | 进入并查看 linux 内核源码目录 )
  4. 【Android 异步操作】手写 Handler ( 循环者 Looper | Looper 初始化 | Looper 遍历消息队列 MessageQueue )
  5. 【IOS 开发】基本 UI 控件详解 (UISegmentedControl | UIImageView | UIProgressView | UISlider | UIAlertView )
  6. 【Android 应用开发】Android 网络编程 API笔记 - java.net 包相关 接口 api
  7. 【Android 应用开发】Android UI 设计之 TextView EditText 组件属性方法最详细解析
  8. Redis 你该懂的点
  9. .Net软件测试化之道 [James D.MCCaffrey]
  10. Redis主从+KeepAlived实现高可用