浏览Ralph Brown's interrupt list, 我发现有很多不同的方法可以将文本字符输出到屏幕上。
ROM BIOS API提供以下功能:
DOS API提供以下功能:
这些功能有什么作用?我怎么称呼他们?我如何在它们之间做出选择?
答案 0 :(得分:11)
所有前面提到的功能在他们完成的任务中都是独一无二的,但是 起初,丰富似乎有些夸大。
Int 21h AH = 02h Write Character To Standard Output
此函数解释字符代码7(Beep),8(退格),9(Tab),
10(换行)和13(回车)。所有其他字符代码都是
显示。
Backspace是非破坏性的,意味着光标将一个位置移动到
离开时没有擦掉下面的东西。 Backspacing停在左边缘
屏幕。
选项卡由此功能扩展。标签扩展是替换的过程
ASCII 9由一系列一个或多个空格(ASCII 32)直到光标到达
列位置是8的倍数
换行将光标向下移动一行,如果需要,滚动屏幕
回车将光标移动到屏幕的最左侧。
Int 21h AH = 06h Direct Console Output
与功能02h非常相似,但不太适合一般使用
不可能输出字符255.仅供参考FAT文件名中的合法字符
它似乎只存在以避免 ctrl C /
ctrl 中断检查。
Int 21h AH = 09h Write String To Standard Output
函数02h的字符串版本,但无法输出字符
因为那个被用作字符串终止符。这是一个主要缺点
因为角色36( $ )不仅是众所周知的货币符号,而且也是
FAT文件名中的合法字符。
Int 21h AH = 40h Write To File Or Device
当与预定义的句柄1一起使用时,该功能输出到STDOUT
默认为屏幕。所以这是显示的另一种可能性
字符。但请注意,它不依赖于字符串终止
性格而不是长度。当然是最完整的输出功能。
它解释了需要解释的内容,并不排除某些内容
字符和它允许捕获重定向错误,虽然后者涉及使用Int 24h handler。
Int 10h AH = 09h Write Character And Attribute At Cursor Position
没有任何字符代码被解释,它们全部显示在屏幕上。
在文本模式下,提供的属性字节同时产生foreground-和
背景颜色,但在图形模式下,您只能获得前景色。
光标位置不会改变。可怜! 1
Int 10h AH = 0Ah Write Character Only At Cursor Position
与文本模式中的函数09h类似,但省略属性字节。
在图形模式下,此功能与功能09h相同。
Int 10h AH = 0Eh Teletype Output
此函数解释字符代码7(Beep),8(Backspace),
10(换行)和13(回车)。所有其他字符代码都是
显示。太糟糕了,这个功能不会扩展标签!
Int 10h AH = 13h Write String
在某种程度上,这是函数0Eh的字符串版本。但是
一般使用缺少标签扩展肯定是一个限制
为什么这么多参数呢? 2
然后选择哪个功能完全取决于您所使用的程序类型 写作。基本上可以在控制台应用程序和完整版之间进行选择 屏幕应用。像CHKDSK.EXE或TREE.COM这样的工具是控制台应用程序。 QBASIC.EXE或NE.COM等程序是全屏应用程序。
控制台应用程序:
面向屏幕的应用程序:
只有DOS输出函数提供所需/推荐的redirection 能力。输出功能02h非常完美。即使它缺乏自己的错误 报告输出时何时发生错误(非常不可能) 重定向,"Abort, Retry, Fail?"的默认严重错误消息 看起来不太合适。 (这是一个全屏应用程序, 相同的信息会极大地破坏屏幕。)
; 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
1 长时间延迟功能请求:使光标前进
接收复制计数为零
2 Retorical,而非实际问题。
3 除非您选择BIOS没有TTY的视频模式
支持。例如。许多BIOS在VESA视频模式下无法滚动。我甚至来了
在传统图形视频模式12h上,无法用功能09h写入字符的BIOS!
4 可以直接在视频内存中写入,但需要更多
努力。