BIOS 级视频编程:INT 10h 功能详解
在计算机编程中,BIOS 级的视频编程是一个关键领域,它允许程序员直接与计算机的视频系统进行交互。本文将深入探讨使用 INT 10h 进行视频编程的相关知识,包括视频文本页面、颜色控制、常见的 INT 10h 功能及其使用方法等。
视频文本页面
在文本模式下,视频内存被划分为多个独立的视频页面,每个页面都可以容纳一整屏的文本。程序可以在显示一个页面的同时,向其他隐藏页面写入文本,并能在不同页面之间快速切换。在高性能 MS - DOS 应用程序盛行的时代,同时在内存中保留多个文本屏幕是很常见的需求。但随着图形界面的普及,这种文本页面功能的重要性已大不如前。默认的视频页面是页面 0。
字符属性与闪烁效果
每个屏幕字符都被分配了一个属性字节,该字节控制着字符的颜色(前景色)和字符背后的屏幕颜色(背景色)。在视频显示中,每个位置都存储着一个字符及其对应的属性(颜色),属性字节紧跟在字符之后存储。
视频显示中的字符可以闪烁。视频控制器通过以预定的速率反转字符的前景色和背景色来实现闪烁效果。默认情况下,当 PC 启动进入 MS - DOS 模式时,闪烁功能是启用的。可以使用视频 BIOS 功能来关闭闪烁。此外,在 MS - Windows 下打开 MS - DOS 模拟窗口时,闪烁功能默认是关闭的。
颜色控制
原色混合
CRT 视频显示器上的每个彩色像素是由红、绿、蓝三个独立的电子束生成的,还有一个第四通道控制像素的整体强度或亮度。因此,所有可用的文本颜色都可以用 4 位二进制值表示,格式为(I - 强度,R - 红色,G - 绿色,B - 蓝色)。通过混合三种原色,可以生成新的颜色,并且通过打开强度位,可以使混合后的颜色更亮。
以下是一些颜色混合的示例:
| 混合原色 | 得到的颜色 | 设置强度位后的颜色 |
| ---- | ---- | ---- |
| 红 + 绿 + 蓝 | 浅灰色 | 白色 |
| 绿 + 蓝 | 青色 | 浅青色 |
| 红 + 蓝 | 品红色 | 浅品红色 |
| 红 + 绿 | 棕色 | 黄色 |
| 无颜色 | 黑色 | 深灰色 |
MS - DOS 风格的原色和混合颜色被编译成一个包含所有可能的 4 位颜色的列表,如下表所示:
| IRGB | 颜色 | IRGB | 颜色 |
| ---- | ---- | ---- | ---- |
| 0000 | 黑色 | 1000 | 灰色 |
| 0001 | 蓝色 | 1001 | 浅蓝色 |
| 0010 | 绿色 | 1010 | 浅绿色 |
| 0011 | 青色 | 1011 | 浅青色 |
| 0100 | 红色 | 1100 | 浅红色 |
| 0101 | 品红色 | 1101 | 浅品红色 |
| 0110 | 棕色 | 1110 | 黄色 |
| 0111 | 浅灰色 | 1111 | 白色 |
属性字节
在彩色文本模式下,每个字符都被分配一个属性字节,该字节由两个 4 位颜色代码组成:背景色和前景色。如果视频适配器当前启用了闪烁功能,背景颜色的高位将控制字符的闪烁。当该位被设置时,字符会闪烁。当闪烁功能启用时,只有上表左列中的低强度颜色(黑色、蓝色、绿色、青色、红色、品红色、棕色和浅灰色)可用作背景颜色。MS - DOS 启动时的默认颜色是二进制 00000111(黑色背景上的浅灰色)。
构建属性字节
要从两种颜色(前景色和背景色)构建一个视频属性字节,可以使用汇编器的 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 用于设置文本光标的大小。文本光标通过起始和结束扫描线来显示,这使得可以控制其大小。应用程序可以利用此功能来显示操作的当前状态。例如,文本编辑器可能会在 NumLock 键被切换打开时增大光标大小,再次按下时,光标恢复到原始大小。
示例代码:
mov ah,1
mov cx,0607h ; 默认彩色光标大小
int 10h
彩色视频显示器的光标使用八条线。
设置光标位置(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 用于将屏幕上矩形区域(称为窗口)内的所有文本向上滚动。窗口是通过其左上角和右下角的行和列坐标来定义的。默认的 MS - DOS 屏幕行号从顶部的 0 到 24,列号从左侧的 0 到 79。因此,覆盖整个屏幕的窗口坐标是从 0,0 到 24,79。
示例代码:
mov ah,6 ; 向上滚动窗口
mov al,0 ; 滚动整行
mov ch,0 ; 左上角行
mov cl,0 ; 左上角列
mov dh,24 ; 右下角行
mov dl,79 ; 右下角列
mov bh,7 ; 空白区域的属性
int 10h ; 调用 BIOS
当窗口向上滚动时,其底部行将被空白行替换。如果所有行都被滚动,窗口将被清除(变为空白),滚动出屏幕的行无法恢复。
以下是一个向窗口写入文本的示例程序(TextWin.asm):
TITLE Color Text Window (TextWin.asm)
; Displays a color window and writes text inside.
INCLUDE Irvine16.inc
.data
message BYTE "Message in Window",0
.code
main PROC
mov ax,@data
mov ds,ax
; Scroll a window.
mov ax,0600h
mov bh,(blue SHL 4) OR yellow
mov cx,050Ah
mov dx,0A30h
int 10h
; Position the cursor inside the window.
mov ah,2
mov dx,0714h
mov bh,0
int 10h
; Write some text in the window.
mov dx,OFFSET message
call WriteString
; Wait for a keypress.
mov ah,10h
int 16h
exit
main ENDP
END main
向下滚动窗口(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 在当前光标位置以彩色写入一个字符。此功能可以显示任何 ASCII 字符,包括与 ASCII 码 1 到 31 匹配的特殊 BIOS 图形字符。CX 中的重复计数指定字符要重复的次数(字符不应在当前屏幕行末尾之后重复)。写入字符后,如果要在同一行写入更多字符,必须调用 INT 10h 功能 2 来移动光标。
示例代码:
mov ah,9
mov al,'A' ; ASCII 字符
mov bh,0 ; 视频页面 0
mov bl,71h ; 属性(浅灰色背景上的蓝色)
mov cx,1 ; 重复计数
int 10h
写入字符后,光标不会自动前进,此功能可在文本和图形模式下调用。
写入字符(0Ah)
INT 10h 功能 0Ah 在当前光标位置写入一个字符,不改变当前屏幕属性。与功能 9 相同,只是不指定属性。
示例代码:
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
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
push ax
push bx
mov ax,1003h
mov bl,1
int 10h
pop bx
ret
EnableBlinking ENDP
该程序在控制台显示一个字符串,每个字符使用不同的颜色。如果要看到字符闪烁,必须以全屏模式运行。默认情况下,闪烁功能是启用的,可以删除对 EnableBlinking 的调用,在深灰色背景上查看相同的字符串。
通过以上对 INT 10h 视频编程功能的详细介绍,我们可以看到它为程序员提供了丰富的工具来实现各种视频显示效果,无论是简单的文本显示还是复杂的彩色字符串输出。在实际编程中,可以根据具体需求选择合适的功能来实现所需的效果。
BIOS 级视频编程:INT 10h 功能详解
不同操作系统下的兼容性问题
在不同的操作系统下运行使用 INT 10h 进行视频编程的程序时,会存在一些兼容性问题。例如,在 Windows 2000、XP 及更高版本中,除非切换到全屏模式,否则默认情况下闪烁功能是禁用的。同样,使用 INT 10h 显示图形时也会受到操作系统的影响。
代码示例总结与分析
下面我们对前面提到的代码示例进行总结和分析,以便更好地理解如何使用 INT 10h 的各个功能。
颜色属性设置示例
; 蓝色背景上的浅灰色文本
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
这些代码展示了如何通过 SHL 和 OR 操作来构建视频属性字节。通过将背景颜色左移四位并与前景颜色进行 OR 运算,可以方便地设置字符的颜色属性。
视频模式设置示例
mov ah,0
mov al,3 ; 视频模式 3(彩色文本)
int 10h
此代码将视频模式设置为彩色文本模式。在设置视频模式时,需要注意屏幕清除的问题,除非设置 AL 中的高位,否则屏幕会自动清除。
光标操作示例
; 设置光标大小
mov ah,1
mov cx,0607h ; 默认彩色光标大小
int 10h
; 设置光标位置
mov ah,2
mov dh,10 ; 行 10
mov dl,20 ; 列 20
mov bh,0 ; 视频页面 0
int 10h
; 获取光标位置和大小
mov ah,3
mov bh,0 ; 视频页面 0
int 10h
mov cursor,CX
mov position,DX
这些代码分别展示了设置光标大小、位置以及获取光标信息的操作。在实际编程中,根据不同的需求可以灵活使用这些功能。
窗口滚动示例
; 向上滚动窗口
mov ah,6 ; 向上滚动窗口
mov al,0 ; 滚动整行
mov ch,0 ; 左上角行
mov cl,0 ; 左上角列
mov dh,24 ; 右下角行
mov dl,79 ; 右下角列
mov bh,7 ; 空白区域的属性
int 10h ; 调用 BIOS
该代码实现了将整个屏幕窗口向上滚动的功能。滚动窗口时,底部行将被空白行替换,滚动出屏幕的行无法恢复。
字符和字符串写入示例
; 写入字符和属性
mov ah,9
mov al,'A' ; ASCII 字符
mov bh,0 ; 视频页面 0
mov bl,71h ; 属性(浅灰色背景上的蓝色)
mov cx,1 ; 重复计数
int 10h
; 以电传模式写入字符串
.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
这些代码分别展示了写入单个字符及其属性和以电传模式写入字符串的操作。在写入字符串时,需要注意写入模式的选择,不同的写入模式会影响光标位置和属性的处理方式。
实际应用场景分析
INT 10h 的视频编程功能在很多实际场景中都有应用,下面我们来分析一些常见的应用场景。
菜单显示
在开发菜单系统时,可以使用 INT 10h 的光标操作功能来控制光标的位置和大小,通过获取光标位置来确定用户选择的菜单选项。同时,可以使用颜色属性设置功能来美化菜单,使不同的菜单选项具有不同的颜色,提高用户体验。
例如,以下是一个简单的菜单显示示例流程:
1. 设置视频模式为合适的文本模式。
2. 使用 INT 10h 功能 13h 以电传模式写入菜单选项字符串。
3. 使用 INT 10h 功能 2 设置光标位置到第一个菜单选项处。
4. 循环监听用户输入,根据用户的上下方向键操作,使用 INT 10h 功能 2 移动光标位置。
5. 根据光标的位置确定用户选择的菜单选项,并执行相应的操作。
文本编辑器
在开发文本编辑器时,INT 10h 的功能也非常有用。可以使用滚动窗口功能来实现文本的滚动显示,使用写入字符和属性功能来显示不同颜色的文本,使用光标操作功能来控制光标的位置和大小。
例如,以下是一个简单的文本编辑器示例流程:
1. 设置视频模式为彩色文本模式。
2. 使用 INT 10h 功能 6 或 7 滚动窗口,以显示更多的文本内容。
3. 使用 INT 10h 功能 9 或 0Ah 写入字符,根据需要设置字符的颜色属性。
4. 使用 INT 10h 功能 2 和 3 控制光标的位置和大小,方便用户输入和编辑文本。
总结与展望
通过本文的介绍,我们深入了解了使用 INT 10h 进行 BIOS 级视频编程的相关知识,包括视频文本页面、颜色控制、常见的 INT 10h 功能及其使用方法等。INT 10h 为程序员提供了丰富的工具来实现各种视频显示效果,无论是简单的文本显示还是复杂的彩色字符串输出。
然而,随着计算机技术的不断发展,现代操作系统和图形库提供了更高级、更方便的视频编程接口。但在一些特定的场景下,如嵌入式系统开发、旧系统维护等,INT 10h 仍然具有重要的价值。
在未来的编程中,我们可以结合现代技术和 INT 10h 的优势,开发出更高效、更美观的视频应用程序。同时,对于初学者来说,学习 INT 10h 的视频编程可以帮助他们更好地理解计算机的底层原理和视频显示机制。
以下是一个简单的 mermaid 流程图,展示了使用 INT 10h 进行视频编程的基本流程:
graph TD;
A[开始] --> B[设置视频模式];
B --> C[设置光标属性];
C --> D[写入字符或字符串];
D --> E{是否需要滚动窗口};
E -- 是 --> F[滚动窗口];
E -- 否 --> G{是否结束程序};
F --> G;
G -- 否 --> D;
G -- 是 --> H[结束];
通过这个流程图,我们可以清晰地看到使用 INT 10h 进行视频编程的基本步骤,从设置视频模式开始,到写入字符或字符串,根据需要进行窗口滚动,最后根据是否结束程序的判断来决定是否继续循环或结束程序。
超级会员免费看
2413

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



