利用BIOS 中断INT 0x10显示字符和字符串
注:以下程序系原创,使用AT&T格式汇编来调用BIOS 0x10中断,如有错误,欢迎指正。表达能力较差,写的不好,但若能帮助一二访客,幸甚。
使用BIOS 显示服务(Video Service)--INT 10H,下面主要探究字符显示模式。
BIOS中断在保护模式下是不能用的,故不能在Linux中测试,所以写了个简单的boot loader,并在虚拟机中运行程序。
1.以电传的方式写入字符串(AH=0x13)
- ------------------------------------------------------------------
- INT 0x10功能0x13
- --------------------------------------------------------------
- 描述:
- 以电传打字机的方式显示字符串
- 接受参数:
- AH 0x13
- AL 显示模式
- BH 视频页
- BL 属性值(如果AL=0x00或0x01)
- CX 字符串的长度
- DH,DL 屏幕上显示起始位置的行、列值
- ES:BP 字符串的段:偏移地址
- 返回值:
- 无
- 显示模式(AL):
- 0x00:字符串只包含字符码,显示之后不更新光标位置,属性值在BL中
- 0x01:字符串只包含字符码,显示之后更新光标位置,属性值在BL中
- 0x02:字符串包含字符码及属性值,显示之后不更新光标位置
- 0x03:字符串包含字符码及属性值,显示之后更新光标位置
- -------------------------------------------------------------------
示例:
- # A bootsect, which print a string by BIOS interrupt video services(int 0x10)
- .section .text
- .global _start
- .code16
- _start:
- movw %cx, %ax
- movw %ax, %ds
- movw %ax, %es
- movw $msgstr,%bp
- movw len, %cx
- movb $0x05, %dh
- movb $0x08, %dl
- movb $0x01, %al
- movb $0x13, %ah
- movb $0x01, %bl
- movb $0x00, %bh
- int $0x10
- 1:
- jmp 1b
- msgstr:
- .asciz "Hello babyos(print by BIOS int 0x10:0x13, mode 0x01)!"
- len:
- .int . - msgstr
- .org 0x1fe, 0x90
- .word 0xaa55
- makefile:
- all: boot.img
- boot.o: boot.s
- as -o $@ $<
- boot: boot.o
- ld --oformat binary -N -Ttext 0x7c00 -o $@ $<
- boot.img: boot
- dd if=boot of=boot.img bs=512 count=1
- clean:
- rm ./boot ./boot.img ./boot.o
运行:
2.通过功能号0x09探究色彩控制
上面的显示为什么是红色呢?我们可以通过实验来看一下颜色控制。
- ------------------------------------------------------------------------
- INT 0x10功能0x09
- -------------------------------------------------------------------
- 描述:
- 显示字符并设置其属性
- 接受参数:
- AH 0x09
- AL 字符的ASCII码
- BH 视频页
- BL 属性值
- CX 重复次数
- 返回值:
- 无
- 注意:
- 在显示字符之后并不前进光标。在文本和图形模式下均可调用该功能
- 显示完字符后,如果还要继续显示字符,必须调用INT 0x10功能0x02前进光标
- -------------------------------------------------------------------------
- ------------------------------------------------------------------------
- INT 0x10功能0x02
- -------------------------------------------------------------------
- 描述:
- 把光标定位在选定视频页的特定行列位置
- 接受参数:
- AH 0x02
- DH,DL 行、列值
- BH 视频页
- 返回值:
- 无
- 注意:
- 在80x25模式下,DH范围0~24,DL范围0~79
- -------------------------------------------------------------------------
示例:
实现一个从第4行~7行,第8列~71列,显示‘A’~‘Z’的程序,共显示256个字符,使用BL(0~255)
C 伪代码:
- cx = 0x04;
- bh = 0x00;
- dh = 0x04;
- dl = 0x08;
- al = 'A';
- for (bl = 0; bl < 256; bl++)
- {
- print_char();
- al++;
- if (al == 'Z')
- al = 'A';
- dl++;
- if (dl == 72)
- {
- dh++;
- dl = 4;
- }
- set_cursor();
- }
汇编代码:
- # A bootsect, which print a colorful chars by BIOS INT 0x10, 0x09
- .section .text
- .global _start
- .code16
- _start:
- movw %cx, %ax
- movw %ax, %ds
- movw %ax, %es
- movw $0x01, %cx # 字符显示重复次数
- movb $0x00, %bh # 视频页
- movb $0x04, %dh # 显示起始行
- movb $0x08, %dl # 显示起始列
- movb $'A', %al # 显示字符
- movb $0x00, %bl # 属性值
- 1:
- call print_char
- incb %al
- cmpb $'Z', %al
- jne 2f
- movb $'A', %al
- 2:
- incb %dl
- cmpb $72, %dl
- jne 3f
- movb $8, %dl
- incb %dh
- 3:
- call set_cursor
- incb %bl
- cmp $256, %bl
- jne 1b
- jmp 1f
- print_char:
- movb $0x09, %ah
- int $0x10
- ret
- set_cursor:
- movb $0x02, %ah
- int $0x10
- ret
- 1:
- jmp 1b
- .org 0x1fe, 0x90
- .word 0xaa55
结果:
可以显式地验证色彩控制BL:
- 7 6 5 4 3 2 1 0
- I R G B I R G B
- 闪烁 R G B I R G B
如上图所示,7~4位为背景色,I表示高亮,RGB表示红绿蓝,若显卡支持闪烁,则位7表示是否闪烁。
色彩混合:
- -----------------------------------------------------------
- 混合的三种基色 不开启亮度位 开启亮度位
- -------------------------------------------------------
- 红+绿+蓝 浅灰 白色
- 绿+蓝 青色 浅青
- 红+蓝 洋红 浅洋红
- 红+绿 棕色 黄色
- 无色彩 黑色 暗灰
- -----------------------------------------------------------
3.清屏
可以发现屏幕上有许多Bochs的打印信息,看着不爽,想办法去掉它们。
利用0x06号功能,上卷全部行,则可清屏。
-----------------------------------------------------------
INT 0x10 功能0x06
------------------------------------------------------
描述:
上卷窗口
参数:
AH 6
AL 上卷的行数(0表示全部)
BH 空白区域的视频属性
CH,CL 窗口左上角的行列位置
DH,DL 窗口右下角的行列位置
返回值:
无
------------------------------------------------------------
示例:
- # A bootsect, which print a colorful chars by BIOS INT 0x10, 0x09
- .section .text
- .global _start
- .code16
- _start:
- movw %cx, %ax
- movw %ax, %ds
- movw %ax, %es
- call clear_screen # 清屏
- movw $0x01, %cx # 字符显示重复次数
- movb $0x00, %bh # 视频页
- movb $0x04, %dh # 显示起始行
- movb $0x08, %dl # 显示起始列
- movb $'A', %al # 显示字符
- movb $0x00, %bl # 属性值
- 1:
- call print_char # 打印字符
- incb %al # 下一个字符
- cmpb $'Z', %al # 是否该重新从‘A’开始
- jne 2f
- movb $'A', %al
- 2:
- incb %dl # 下一个位置
- cmpb $72, %dl # 是否到下一行
- jne 3f
- movb $8, %dl
- incb %dh
- 3:
- call set_cursor # 设置光标位置
- incb %bl # 下一种属性
- cmp $0, %bl # 是否256种属性用完
- jne 1b
- jmp 1f # 结束
- clear_screen: # 清屏函数
- movb $0x06, %ah # 功能号0x06
- movb $0, %al # 上卷全部行,即清屏
- movb $0, %ch # 左上角行
- movb $0, %ch # 左上角列
- movb $24, %dh # 右下角行
- movb $79, %dl # 右下角列
- movb $0x07, %bh # 空白区域属性
- int $0x10
- ret
- print_char:
- movb $0x09, %ah # 功能号0x09
- int $0x10
- ret
- set_cursor:
- movb $0x02, %ah # 功能号0x02
- int $0x10
- ret
- 1:
- jmp 1b
- .org 0x1fe, 0x90
- .word 0xaa55
结果:
4.直接写显存绘制字符串:
示例:
- #---------------------------------------------------------------
- # 直接写显存显示一些文字函数:
- # 显示计算机当前工作的显示模式
- draw_some_text:
- # 设置ES,DS的值
- movw $VIDEO_SEG_TEXT,%ax
- movw %ax, %es
- xorw %ax, %ax
- movw %ax, %ds
- # 计算字符显示位置的显存地址(目标地址)
- movw $((80*TEXT_ROW+TEXT_COL) * 2), %di
- # 源字符串地址
- leaw msgstr, %si
- movb $TEXT_COLOR, %al # 属性值(颜色)
- movw len, %cx # 显示的字符个数
- draw_a_char:
- movsb
- stosb
- loop draw_a_char
- ret
利用BIOS 中断INT 0x10显示字符和字符串相关推荐
- 3. 51——LCD1602显示 字符、字符串、数字
51--LCD1602显示 字符.字符串.数字 LCD1602简介 LCD1602相关引脚 LCD1602写命令.写数据相关操作图 写指令 代码 写数据 代码 LCD1602显示程序步骤及如何初始化 ...
- PIC单片机利用视觉暂留现象显示字符
Persistance of Vision (PoV), 即视觉暂留现象, 人眼在观察景物时,光信号传人大脑神经,需经过一段短暂的时间,光的作用结束后,视觉形象并不立即消失,这种残留的视觉称" ...
- 一步步编写操作系统 34 内核利用bios中断获取物理内存大小
接上文,另一个获取内存容量的方法是bios 0x15中断的子功能0xE801. 此方法虽然简单,但功能也不强大,最大只能识别4G内存,不过这对咱们32位地址总线足够了.稍微有点不便的是,此方法检测到的 ...
- 一步步编写操作系统 33 利用bios中断0x15子功能0xe820获取内存
咱们先介绍0xE820子功能,这是最灵活的内存获取方式. bios中断 0x15的子功能0xE820能够获取系统的内存布局,由于系统内存各部分的类型属性不同,bios就按照类型属性来划分这片系统内存, ...
- 51单片机LCD1602液晶屏显示字符,字符串,(有)无符号整数,十六进制数,二进制数等
1.前言 LCD1602液晶显示器是广泛使用的一种字符型液晶显示模块.液晶显示模块具有体积小.功耗低.显示内容丰富.超薄轻巧等优点,在嵌入式应用系统中得到越来越广泛的应用,这讲中向大家介绍的LCD16 ...
- babyos (三)——利用BIOS INT 0x13读取软盘
注:以下程序为原创,若发现任何BUG,欢迎指正:若有问题,欢迎交流:权利归原作者所有,若转载,请注明出处:若能有益于一二访客,幸甚. 昨天学习了VGA显示的一些东西,今天准备学习一下读取软盘的知识. ...
- BIOS中断大全:“INT 10H ~ INT 1AH”
BIOS中断: 1.显示服务(Video Service--INT 10H) 00H -设置显示器模式 01H -设置光标形状 02H -设置光标位置 03H -读取光标信息 04H -读取光笔位置 ...
- cmos 和 bios中断大全
1,cmos简介. cmos是主板上一块可读写的RAM芯片.用途:主要用来保存当前系统的硬件配置和操作人员对某些参数的设定.cmos芯片是由一块纽扣电池供电.因此在关机状态内部信息也不会丢失. ...
- STM32 OLED显示字符汉字
本文代码使用 HAL 库. 文章目录 前言 一. OLED 接线: 二.点阵: 三.写数据,命令函数 四.显示字符,字符串: 总结 前言 OLED 屏幕是一种高对比度.高亮度.低功耗.灵活可弯曲的显示 ...
最新文章
- Java集合,ConcurrentHashMap底层实现和原理(常用于并发编程)
- VS调试python中的DLL
- 广义逆高斯分布及推广(To be continued)
- EasyUI学习总结(一)——EasyUI入门
- java main是标识符吗_main方法的认识 、通配符、java的注释、java的符(标识符)【Java基础】...
- oracle 增量_【干货分享】DMETL中的增量抽取初识
- Js 获取当前页面的高度
- 沈抚示范区·“华为云杯”2021全国AI大赛圆满落幕
- 女生适合当程序员吗?
- Windows下用C语言连接Mysql注意问题
- sqlserver数据库置疑处理
- Windows 7 修改系统临时文件夹
- Strut2的工作流程
- imovie导入媒体没有声音的解决办法
- 新应用——信息化财务管理,一站式满足多个需求
- matlab成功安装libsvm后,运行程序仍报错“svmtrain has been removed”解决方法记录
- vue 拖拽功能样式优化
- Mac电脑 绑定阿里云企业邮箱
- 基于Redis的BloomFilter实现
- 《游戏改变世界》读后感 一 (懊悔?and我眼中的好游戏)
热门文章
- UVA11384正整数序列(把123..变成0的最小步数)
- 【Linux 内核】进程管理 ( Linux 内核中的进程状态 | TASK_RUNNING | TASK_INTERRUPTIBLE | __TASK_STOPPED | EXIT_ZOMBIE )
- 【Linux 内核】编译 Linux 内核 ② ( 解压内核源码 | 查询当前 Linux 内核版本号 | 进入并查看 linux 内核源码目录 )
- 【Android 异步操作】手写 Handler ( 循环者 Looper | Looper 初始化 | Looper 遍历消息队列 MessageQueue )
- 【IOS 开发】基本 UI 控件详解 (UISegmentedControl | UIImageView | UIProgressView | UISlider | UIAlertView )
- 【Android 应用开发】Android 网络编程 API笔记 - java.net 包相关 接口 api
- 【Android 应用开发】Android UI 设计之 TextView EditText 组件属性方法最详细解析
- Redis 你该懂的点
- .Net软件测试化之道 [James D.MCCaffrey]
- Redis主从+KeepAlived实现高可用