60、BIOS 级视频编程:INT 10h 功能详解

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 进行视频编程的基本步骤,从设置视频模式开始,到写入字符或字符串,根据需要进行窗口滚动,最后根据是否结束程序的判断来决定是否继续循环或结束程序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值