查看Ralph Brown的中断列表, 我发现有许多不同的方法可以将文本字符输出到屏幕。
ROM BIOS API 提供以下功能:
- AH=09h – 在光标位置写入字符和属性
- AH=0Ah – 仅在光标位置写入字符
- AH=0Eh – 电传打字输出
- AH=13h – 写入字符串
DOS API提供以下功能:
- AH=02h – 将字符写入标准输出
- AH=06h – 直接控制台输出
- AH=09h – 将字符串写入标准输出
这些功能有什么作用?我该如何称呼他们?我该如何在它们之间进行选择?
上述所有功能在完成的任务上都是独一无二的,但是 起初,丰富似乎有些夸张。
-
国际 21h AH=02h 将字符写入标准输出
此函数解释字符代码 7(蜂鸣声)、8(退格键)、9(制表符)、 10(换行)和 13(回车)。所有其他字符代码均为 显示。
退格键是非破坏性的,这意味着光标将一个位置移动到 离开而不抹去下面的东西。后间距在左边缘停止 的屏幕。
选项卡通过此功能展开。选项卡扩展是替换的过程 ASCII 9 由一系列一个或多个空格 (ASCII 32) 组成,直到光标到达 列位置是 8 的倍数。
换行将光标向下移动一行,并在需要时滚动屏幕。
回车会将光标移动到屏幕的最左侧。 -
Int 21h AH=06h 直接控制台输出
与函数 02h 非常相似,但不太适合一般用途,因为它是 无法输出字符 255。仅供参考,FAT文件名中的法律字符。
它的存在似乎只是为了避免ctrlC/ctrl中断检查。 -
Int 21h AH=09h 将字符串写入标准输出
函数 02h 的字符串版本,但无法输出字符 36,因为那个用作字符串终止符。这是一个主要缺点 由于字符 36 ($) 不仅是众所周知的货币符号,而且 FAT 文件名中的合法字符。 -
Int 21h AH=40h 写入文件或设备
当与预定义句柄 1 一起使用时,此函数输出到 STDOUT, 默认为屏幕。所以这里有另一种显示的可能性 字符。但请注意,它不依赖于字符串终止 性格,但更像是一个长度。当然是最完整的输出功能。 它解释需要解释的内容,它不排除某些 字符,它允许捕获重定向错误,尽管后者涉及使用 Int 24h 处理程序。 -
Int 10h AH=09h 在光标位置写入字符和属性
没有字符代码被解释,它们都显示在屏幕上。 在文本模式下,提供的属性字节同时生成前台和 背景色,但在图形模式下,您只能获得前景色。 光标位置不会更改。可惜!1 -
int 10h AH=0Ah 仅在光标位置写入字符
类似于文本模式下的函数 09h,但省略了属性字节。 在图形模式下,此功能与函数 09h 相同。 -
Int 10h AH=0Eh 电传打字输出
此函数解释字符代码 7(蜂鸣声)、8(退格键)、 10(换行)和 13(回车)。所有其他字符代码均为 显示。太糟糕了,这个功能不会展开选项卡! -
Int 10h AH=13h 写入字符串
在某种程度上,这是函数 0Eh 的字符串版本。然而对于 一般用途 缺少选项卡扩展当然是一个限制。
为什么有这么多参数?阿拉伯数字
选择哪个功能完全取决于您是哪种程序 写作。基本上,可以在控制台应用程序和完整应用程序之间进行选择 屏幕应用程序。CHKDSK.EXE 或 TREE.COM 等工具是控制台应用程序。 像QBASIC.EXE或 NE.COM 这样的程序是全屏应用程序。
控制台应用程序:
- 不在乎使用颜色
- 以线性方式将其输出写入屏幕上
- 不会妨碍操作系统的输出重定向能力
- 通常执行单个任务
- 通常在眨眼间终止
面向屏幕的应用程序:
- 使用适量的颜色受益匪浅
- 在屏幕上徘徊,在它想要的地方写下它想要的东西
- 无需担心输出重定向,因为上述内容很快就会足够 使此类输出不可读
- 经常执行(太多)许多任务
- 继续下去,直到你决定是时候退出了
控制台应用程序
只有 DOS 输出功能提供必需/推荐的重定向 能力。输出功能02h是完美的。即使它没有自己的错误 报告何时应发生错误(非常不可能),而输出 重定向,默认严重错误消息"中止、重试、失败? 看起来并没有太不合适。(如果这是一个全屏应用程序, 同样的信息会极大地扰乱屏幕。
; IN (ds:si) OUT ()
WriteStringDOS:
pusha
jmps .b
.a: mov dl,al
mov ah,02h
int 21h ;DOS.DisplayCharacter -> AL
.b: lodsb
test al,al
jnz .a
popa
ret
但是,有时您需要显示临时项目,例如:
- 某种提示("-- 更多 --"、"准备好时按键..."等)
- 一个运行计数器/百分比
- 进度条
为了避免弄乱任何重定向的输出,最好不要使用DOS 这些临时项的输出函数。最好使用接下来的WriteStringBIOS代码。
全屏应用
现在输出重定向是你的敌人,所以不要使用任何 DOS 输出函数。 如果你不需要颜色,那么下一个代码片段适合你。它基本上 将选项卡扩展添加到 BIOS 电传打字功能。
; IN (ds:si) OUT ()
WriteStringBIOS:
pusha
mov bx,0007h ;Display page 0, Color if graphics mode
jmps .b
.a: cmp al,9
je .Tab
mov ah,0Eh
int 10h ;BIOS.Teletype
.b: lodsb
test al,al
jnz .a
popa
ret
.Tab: mov ax,0E20h ;Start displaying space(s)
int 10h ;BIOS.Teletype
mov ah,03h
int 10h ;BIOS.GetCursor -> CX DX
test dl,7
jnz .Tab ;Column not yet multiple of 8
jmps .b
大多数时候,一点颜色会创造奇迹。以下代码片段使用 BIOS 功能 09h 用于输出彩色字符和 BIOS 功能 0Eh 到 前进光标。一个很好的组合,让事情变得简单。
在文本视频模式下使用第一个:
; IN (bl,ds:si) OUT ()
WriteStringWithAttributeTVM:
pusha
mov bh,0 ;Display page 0
jmps .d
.a: cmp al,9
je .Tab
cmp al,13
ja .b
mov cx,1101_1010_0111_1111b
bt cx,ax
jnc .c ;7,8,10,13 don't need the color
.b: mov cx,1
mov ah,09h
int 10h ;BIOS.WriteCharacterAndAttribute
.c: mov ah,0Eh
int 10h ;BIOS.Teletype
.d: lodsb
test al,al
jnz .a
popa
ret
.Tab: mov cx,1 ;Start displaying colored space(s)
mov ax,0920h ;ASCII 20h is space character
int 10h ;BIOS.WriteCharacterAndAttribute
mov ah,0Eh
int 10h ;BIOS.Teletype
mov ah,03h
int 10h ;BIOS.GetCursor -> CX DX
test dl,7
jnz .Tab ;Column not yet multiple of 8
jmps .d
在16彩色图形视频模式下使用第二个。它涉及更多 因为 BIOS 拒绝绘制背景颜色。
; IN (bl,ds:si) OUT ()
WriteStringWithAttributeGVM:
pusha
mov bh,0 ;Display page 0
mov bp,bx
jmps .d
.a: cmp al,9
je .Tab
cmp al,13
ja .b
mov cx,1101_1010_0111_1111b
bt cx,ax
jnc .c ;7,8,10,13 don't need the color
.b: push ax
mov cx,1
mov bx,bp
shr bl,4 ;Get background color (high nibble)
mov ax,09DBh ;ASCII DBh is full block character
int 10h ;BIOS.WriteCharacterAndAttribute
xor bx,bp ;Anticipate upcoming 'xor'
and bl,15 ;Get foreground color (low nibble)
or bl,128 ;Have BIOS 'xor' it
pop ax
.c: mov ah,0Eh
int 10h ;BIOS.Teletype
.d: lodsb
test al,al
jnz .a
popa
ret
.Tab: mov cx,1 ;Start displaying colored space(s)
mov bx,bp
shr bl,4 ;Get background color
mov ax,0EDBh ;ASCII DBh is full block character
int 10h ;BIOS.Teletype
mov ah,03h
int 10h ;BIOS.GetCursor -> CX DX
test dl,7
jnz .Tab ;Column not yet multiple of 8
jmps .d
总结
- 对于控制台应用程序,WriteStringDOS和WriteStringBIOS过程绰绰有余3.
- 对于全屏应用程序,WriteStringWithAttributeTVM和WriteStringWithAttributeGVM过程平均提供34。
- DOS和BIOS都不足以处理图形视频 模式。要么编写自己的图形例程(不是微不足道的任务!),要么使用 第三方图形库。
1长时间延迟的功能请求:使光标前进 接收的复制计数为零。
2反转,不是实际问题。
3除非您选择的 BIOS 没有 TTY 的视频模式 支持。例如。许多 BIOS 在 VESA 视频模式下无法滚动。我什至来了 在无法在传统图形视频模式 12h 上写入具有功能 09h 的字符的 BIOS 上!
4可以直接在显存中写入是可能的,但需要更多 努力。