BIOS 级编程中的视频编程:INT 10h 功能详解
在计算机编程领域,BIOS 级编程中的视频编程是一个重要的方面。它涉及到对计算机屏幕显示的控制,包括文本页面、颜色设置、光标操作等。本文将详细介绍使用 INT 10h 进行视频编程的相关知识。
视频文本页面
在文本模式下,视频内存被划分为多个独立的视频页面,每个页面都可以容纳一整屏的文本。程序可以在显示一个页面的同时,向其他隐藏页面写入文本,并能在不同页面之间快速切换。在高性能 MS - DOS 应用程序盛行的时代,同时在内存中保留多个文本屏幕是很常见的需求。然而,随着图形界面的普及,这种文本页面功能的重要性已经大不如前。默认的视频页面是页面 0。
字符属性与颜色控制
每个屏幕字符都被分配了一个属性字节,该字节控制着字符的颜色(前景色)和字符背后的屏幕颜色(背景色)。在视频显示中,每个位置都包含一个字符及其对应的属性(颜色),属性存储在内存中字符之后的一个单独字节里。
颜色混合
CRT 视频显示器上的每个彩色像素是由红、绿、蓝三个独立的电子束生成的,还有一个第四通道控制像素的整体强度或亮度。所有可用的文本颜色都可以用 4 位二进制值表示,形式为(I - 强度,R - 红色,G - 绿色,B - 蓝色)。通过混合三种原色,可以生成新的颜色,并且打开强度位可以使混合颜色更亮。
| 混合原色 | 得到的颜色 | 打开强度位后的颜色 |
|---|---|---|
| 红 + 绿 + 蓝 | 浅灰色 | 白色 |
| 绿 + 蓝 | 青色 | 浅青色 |
| 红 + 蓝 | 品红色 | 浅品红色 |
| 红 + 绿 | 棕色 | 黄色 |
| 无颜色 | 黑色 | 深灰色 |
4 位颜色文本编码
MS - DOS 风格的原色和混合颜色被编译成一个包含所有可能的 4 位颜色的列表。
| IRGB | 颜色 | IRGB | 颜色 |
|---|---|---|---|
| 0000 | 黑色 | 1000 | 灰色 |
| 0001 | 蓝色 | 1001 | 浅蓝色 |
| 0010 | 绿色 | 1010 | 浅绿色 |
| 0011 | 青色 | 1011 | 浅青色 |
| 0100 | 红色 | 1100 | 浅红色 |
| 0101 | 品红色 | 1101 | 浅品红色 |
| 0110 | 棕色 | 1110 | 黄色 |
| 0111 | 浅灰色 | 1111 | 白色 |
构建属性字节
在彩色文本模式下,每个字符都被分配一个属性字节,它由两个 4 位颜色代码组成:背景色和前景色。要从两种颜色(前景色和背景色)构建一个视频属性字节,可以使用汇编器的 SHL 运算符将背景颜色位向左移动四位,然后与前景颜色进行 OR 运算。
以下是一些示例代码:
; 蓝色背景上的浅灰色文本
blue = 1
lightGray = 111b
mov bh,(blue SHL 4) OR lightGray
; 结果: 00010111
; 红色背景上的白色字符
white = 1111b
red = 100b
mov bh,(red SHL 4) OR white
; 结果: 01001111
; 棕色背景上的蓝色字母
blue = 1
brown = 110b
mov bh,((brown SHL 4) OR blue)
; 结果: 01100001
INT 10h 视频功能
INT 10h 提供了一系列用于视频编程的功能,以下是一些常用的功能及其说明:
| 功能编号 | 描述 |
|---|---|
| 0 | 将视频显示设置为文本或图形模式之一 |
| 1 | 设置光标线条,控制光标形状和大小 |
| 2 | 在屏幕上定位光标 |
| 3 | 获取光标在屏幕上的位置和大小 |
| 6 | 将当前视频页面上的一个窗口向上滚动,用空白替换滚动的行 |
| 7 | 将当前视频页面上的一个窗口向下滚动,用空白替换滚动的行 |
| 8 | 读取当前光标位置的字符及其属性 |
| 9 | 在当前光标位置写入一个字符及其属性 |
| 0Ah | 在当前光标位置写入一个字符,不改变颜色属性 |
| 0Ch | 在图形模式下在屏幕上写入一个图形像素 |
| 0Dh | 读取给定位置的单个图形像素的颜色 |
| 0Fh | 获取当前视频模式信息 |
| 10h | 设置闪烁/强度模式 |
| 13h | 以电传模式写入字符串 |
| 1Eh | 以电传模式向屏幕写入字符串 |
在调用 INT 10h 之前,最好使用 PUSH 指令保存通用寄存器,因为不同的 BIOS 版本在保留哪些寄存器方面并不一致。
具体功能操作
设置视频模式(00h)
INT 10h 功能 0 可以将当前视频模式设置为文本或图形模式之一。以下是一些常见的文本模式:
| 模式 | 分辨率(列 X 行) | 颜色数量 |
|---|---|---|
| 0 | 40 × 25 | 16 |
| 1 | 40 × 25 | 16 |
| 2 | 80 × 25 | 16 |
| 3 | 80 × 25 | 16 |
| 7a | 80 × 25(单色显示器) | 2 |
| 14h | 132 × 25 | 16 |
示例代码:
mov ah,0
mov al,3
; 视频模式 3(彩色文本)
int 10h
注意:除非在调用此功能之前设置 AL 中的高位,否则屏幕会自动清除。
设置光标线条(01h)
INT 10h 功能 01h 用于设置文本光标的大小。文本光标通过起始和结束扫描线显示,从而可以控制其大小。
示例代码:
mov ah,1
mov cx,0607h ; 默认彩色光标大小
int 10h
彩色视频显示器的光标使用 8 条线。默认的彩色光标从第 6 行开始,到第 7 行结束。
设置光标位置(02h)
INT 10h 功能 2 可以将光标定位在所选视频页面的特定行和列上。
示例代码:
mov ah,2
mov dh,10 ; 第 10 行
mov dl,20 ; 第 20 列
mov bh,0 ; 视频页面 0
int 10h
对于 80 × 25 模式,DH 的取值范围是 0 到 24,DL 的取值范围是 0 到 79。
获取光标位置和大小(03h)
INT 10h 功能 3 可以返回光标在屏幕上的行/列位置以及确定光标大小的起始和结束行。
示例代码:
mov ah,3
mov bh,0 ; 视频页面 0
int 10h
mov cursor,CX
mov position,DX
显示和隐藏光标
在显示菜单、连续向屏幕写入或读取鼠标输入时,临时隐藏光标是很有用的。可以通过将光标顶行值设置为非法(大)值来隐藏光标,将光标行恢复为默认值(第 6 行和第 7 行)来重新显示光标。
HideCursor PROC
mov
ah,3
; 获取光标大小
int
10h
or
ch,30h
; 设置上行为非法值
mov
ah,1
; 设置光标大小
int
10h
ret
HideCursor ENDP
ShowCursor PROC
mov
ah,3
; 获取光标大小
int
10h
mov
ah,1
; 设置光标大小
mov
cx,0607h
; 默认大小
int
10h
ret
ShowCursor ENDP
不过,这种隐藏光标的方法并不总是有效,另一种方法是使用 INT 10h 功能 02h 将光标定位到屏幕边缘之外(例如第 25 行)。
向上滚动窗口(06h)
INT 10h 功能 6 可以将屏幕上一个矩形区域(窗口)内的所有文本向上滚动。窗口由其左上角和右下角的行和列坐标定义。
示例代码:
mov ah,6
; 向上滚动窗口
mov al,0
; 整个窗口
mov ch,0
; 左上角行
mov cl,0
; 左上角列
mov dh,24
; 右下角行
mov dl,79
; 右下角列
mov bh,7
; 空白区域的属性
int 10h
; 调用 BIOS
向下滚动窗口(07h)
滚动窗口向下的功能与功能 06h 相同,只是窗口内的文本向下移动,使用相同的输入参数。
读取字符和属性(08h)
INT 10h 功能 8 可以返回当前光标位置的字符及其属性,可用于直接从屏幕读取文本。
示例代码:
mov ah,8
mov bh,0 ; 视频页面 0
int 10h
mov char,al ; 保存字符
mov attrib,ah ; 保存属性
写入字符和属性(09h)
INT 10h 功能 9 可以在当前光标位置以彩色写入一个字符,CX 中的重复计数指定字符要重复的次数。
示例代码:
mov ah,9
mov al,'A' ; ASCII 字符
mov bh,0 ; 视频页面 0
mov bl,71h ; 属性(浅灰色背景上的蓝色)
mov cx,1 ; 重复计数
int 10h
注意:写入字符后不会自动推进光标,如果要在同一行写入更多字符,必须调用 INT 10h 功能 2 来推进光标。
写入字符(0Ah)
INT 10h 功能 0Ah 可以在当前光标位置写入一个字符,不改变当前屏幕属性。
示例代码:
mov ah,0Ah
mov al,'A' ; ASCII 字符
mov bh,0 ; 视频页面 0
mov cx,1 ; 重复计数
int 10h
写入字符后不会推进光标。
获取视频模式信息(0Fh)
INT 10h 功能 0Fh 可以返回当前视频模式的信息,包括模式编号、显示列数和活动视频页面编号。
示例代码:
mov ah,0Fh
int 10h
mov vmode,al ; 保存模式
mov columns,ah ; 保存列数
mov page,bh ; 保存页面
此功能在文本和图形模式下都适用。
设置闪烁/强度模式(10h; 03h)
INT 10h 功能 10h 的子功能 03h 允许颜色属性的最高位控制颜色强度或使字符闪烁。
示例代码:
mov ah,10h
mov al,3
mov bl,1 ; 启用闪烁
int 10h
在 MS - Windows 下,只有在应用程序以全屏模式运行时才能实现闪烁。
以电传模式写入字符串(13h)
INT 10h 功能 13h 可以在给定的行和列位置以电传模式向屏幕写入一个字符串,字符串可以包含字符和属性值。
示例代码:
.data
colorString BYTE 'A',1Fh,'B',1Ch,'C',1Bh,'D',1Ch
row BYTE 10
column BYTE 20
.code
mov ax,SEG colorString ; 设置 ES 段
mov es,ax
mov ah,13h ; 写入字符串
mov al,2 ; 写入模式
mov bh,0 ; 视频页面
mov cx,(SIZEOF colorString) / 2 ; 字符串长度
mov dh,row ; 起始行
mov dl,column ; 起始列
mov bp,OFFSET colorString ; 字符串偏移量
int 10h
写入模式值有以下几种:
- 00h - 字符串只包含字符代码;写入后光标不更新,属性在 BL 中。
- 01h - 字符串只包含字符代码;写入后光标更新,属性在 BL 中。
- 02h - 字符串包含交替的字符代码和属性字节;写入后光标位置不更新。
- 03h - 字符串包含交替的字符代码和属性字节;写入后光标位置更新。
示例程序:显示彩色字符串
以下是一个示例程序(ColorStr.asm),用于在控制台显示一个字符串,每个字符使用不同的颜色。如果要看到字符闪烁,必须以全屏模式运行该程序。
TITLE Color String Example (ColorStr.asm)
INCLUDE Irvine16.inc
.data
ATTRIB_HI = 10000000b
string BYTE "ABCDEFGHIJKLMOP"
color BYTE (black SHL 4) OR blue
.code
main PROC
mov
ax,@data
mov
ds,ax
call
ClrScr
call
EnableBlinking
; 这是可选的
mov
cx,SIZEOF string
mov
si,OFFSET string
L1:
push
cx
; 保存循环计数器
mov
ah,9
; 写入字符/属性
mov
al,[si]
; 要显示的字符
mov
bh,0
; 视频页面 0
mov
bl,color
; 属性
or
bl,ATTRIB_HI
; 设置闪烁/强度位
mov
cx,1
; 显示一次
int
10h
mov
cx,1
; 推进光标到
call
AdvanceCursor
; 下一个屏幕列
inc
color
; 下一种颜色
inc
si
; 下一个字符
pop
cx
; 恢复循环计数器
loop
L1
call
Crlf
exit
main ENDP
;--------------------------------------------------
EnableBlinking PROC
;
; 启用闪烁(使用颜色属性的高位)。在 MS - Windows 中,只有当程序以全屏模式运行时才有效。
; 接收: 无。返回: 无
;--------------------------------------------------
push
ax
push
bx
mov
ax,1003h
; 设置闪烁/强度模式
mov
bl,1
; 启用闪烁
int
10h
pop
bx
通过以上介绍,我们可以看到使用 INT 10h 进行视频编程可以实现对计算机屏幕显示的多种控制,包括文本页面管理、颜色设置、光标操作和字符串显示等。在实际编程中,需要根据具体需求选择合适的功能,并注意不同功能的参数设置和使用方法。同时,要考虑不同操作系统对显示效果的影响,以确保程序在各种环境下都能正常运行。
BIOS 级编程中的视频编程:INT 10h 功能详解
视频编程的综合应用与注意事项
在实际的视频编程中,我们常常需要综合运用 INT 10h 的多个功能来实现复杂的显示效果。下面我们通过一个综合示例来展示如何结合这些功能创建一个动态的彩色文本显示界面。
TITLE Dynamic Color Text Display (DynamicText.asm)
INCLUDE Irvine16.inc
.data
message BYTE "Dynamic Text Display Example", 0
color1 BYTE (blue SHL 4) OR lightGray
color2 BYTE (red SHL 4) OR yellow
row BYTE 10
column BYTE 20
.code
main PROC
mov ax, @data
mov ds, ax
; 设置视频模式为彩色文本模式
mov ah, 0
mov al, 3
int 10h
; 隐藏光标
call HideCursor
; 循环显示文本,每次改变颜色
mov cx, 10
L1:
; 设置光标位置
mov ah, 2
mov dh, row
mov dl, column
mov bh, 0
int 10h
; 写入字符和属性
mov si, OFFSET message
L2:
mov al, [si]
cmp al, 0
je EndOfString
mov ah, 9
mov bh, 0
cmp cx, 5
jge UseColor1
mov bl, color2
jmp WriteChar
UseColor1:
mov bl, color1
WriteChar:
mov cx, 1
int 10h
inc si
jmp L2
EndOfString:
; 等待一段时间
mov ah, 0
mov al, 100 ; 等待 100 毫秒
int 1Ah
loop L1
; 显示光标
call ShowCursor
; 恢复原始视频模式
mov ah, 0Fh
int 10h
mov al, vmode
mov ah, 0
int 10h
exit
main ENDP
HideCursor PROC
mov ah, 3
int 10h
or ch, 30h
mov ah, 1
int 10h
ret
HideCursor ENDP
ShowCursor PROC
mov ah, 3
int 10h
mov ah, 1
mov cx, 0607h
int 10h
ret
ShowCursor ENDP
在这个示例中,我们首先设置了视频模式为彩色文本模式,然后隐藏了光标。接着,我们在一个循环中多次显示文本消息,每次显示时根据循环次数选择不同的颜色。在每次显示完文本后,程序会等待一段时间,以实现动态效果。最后,我们显示光标并恢复原始的视频模式。
视频编程的流程图
下面是一个使用 mermaid 格式绘制的流程图,展示了上述综合示例的主要流程:
graph TD;
A[开始] --> B[设置视频模式];
B --> C[隐藏光标];
C --> D[循环 10 次];
D --> E[设置光标位置];
E --> F[写入文本并选择颜色];
F --> G[等待一段时间];
G --> D;
D --> H[显示光标];
H --> I[恢复原始视频模式];
I --> J[结束];
不同操作系统下的兼容性问题
在不同的操作系统下,使用 INT 10h 进行视频编程可能会遇到一些兼容性问题。例如,在 Windows 2000、XP 及更高版本中,除非切换到全屏模式,否则字符闪烁功能将被禁用。同样,使用 INT 10h 显示图形时也会受到操作系统的限制。
为了确保程序在不同操作系统下的兼容性,我们可以采取以下措施:
1.
检测操作系统
:在程序开始时,使用操作系统提供的功能检测当前运行的操作系统版本,根据不同的版本采取不同的处理方式。
2.
提供替代方案
:对于某些在特定操作系统下无法实现的功能,提供替代方案。例如,如果字符闪烁在当前操作系统下不可用,可以使用颜色变化来替代闪烁效果。
3.
测试和调试
:在不同的操作系统和硬件环境下对程序进行充分的测试和调试,及时发现并解决兼容性问题。
常见错误及解决方法
在使用 INT 10h 进行视频编程时,常见的错误包括:
1.
参数设置错误
:每个 INT 10h 功能都有特定的参数要求,如果参数设置不正确,可能会导致功能无法正常工作。解决方法是仔细阅读文档,确保参数设置正确。
2.
光标位置问题
:某些功能可能会影响光标位置,导致后续的显示出现混乱。在使用这些功能时,要注意保存和恢复光标位置。
3.
颜色显示异常
:由于不同的硬件和操作系统对颜色的解释可能不同,可能会出现颜色显示异常的问题。可以通过调整颜色代码或使用标准的颜色设置来解决。
总结
通过本文的介绍,我们深入了解了使用 INT 10h 进行视频编程的相关知识,包括视频文本页面、字符属性与颜色控制、各种 INT 10h 功能的使用方法以及实际应用中的综合示例。在进行视频编程时,我们需要综合考虑多个因素,如功能的选择、参数的设置、不同操作系统的兼容性以及常见错误的处理。通过合理运用这些知识和技巧,我们可以实现各种复杂的视频显示效果,为用户带来更好的视觉体验。
希望本文能够对您在 BIOS 级视频编程方面有所帮助,让您在编程的道路上更加得心应手。在未来的编程实践中,您可以根据自己的需求进一步探索和扩展这些功能,创造出更加精彩的程序。
超级会员免费看
2413

被折叠的 条评论
为什么被折叠?



