Sep*_*and 5 x86 assembly dos bios
通过Ralph Brown的中断列表,我发现有许多不同的方法可以将文本字符输出到屏幕上.
ROM BIOS API提供以下功能:
DOS API提供以下功能:
这些功能有什么作用?我怎么称呼他们?我如何在它们之间做出选择?
Sep*_*and 13
所有前面提到的功能在它们完成的任务中都是独一无二的,但首先,丰度似乎有点夸大.
Int 21h AH = 02h 将字符写入标准输出
此功能解释字符代码7(蜂鸣声),8(退格),9(标签),10(换行)和13(回车).显示所有其他字符代码.
Backspace是非破坏性的,意味着光标向左移动一个位置而不擦除下面的内容.Backspacing停在屏幕的左边缘.
选项卡由此功能扩展.选项卡扩展是通过一系列一个或多个空格(ASCII 32)替换ASCII 9的过程,直到光标到达8的倍数的列位置.
换行将光标向下移动一行,如果需要则滚动屏幕.
回车将光标移动到屏幕的最左侧.
Int 21h AH = 06h 直接控制台输出
非常类似于功能02h,但不太适合一般用途,因为无法输出字符255.FYI是FAT文件名中的合法字符.
它似乎完全存在以避免ctrlC/
ctrlBreak检查.
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 Teletype输出
此功能解释字符代码7(Beep),8(退格),10(换行)和13(回车).显示所有其他字符代码.太糟糕了,这个功能不会扩展标签!
Int 10h AH = 13h Write String
在某种程度上,这是函数0Eh的字符串版本.然而,对于一般用途,缺少标签扩展肯定是一个限制.
为什么这么多参数呢?2
选择哪个功能完全取决于您正在编写的程序类型.基本上可以在控制台应用程序和全屏应用程序之间进行选择.像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
Run Code Online (Sandbox Code Playgroud)
但有时你会想要显示一个临时项目,如:
为了避免弄乱任何重定向输出,最好不要在这些临时项上使用DOS输出函数.最好使用 下一步的WriteStringBIOS代码.
现在输出重定向是你的敌人,所以不要使用任何DOS输出函数.如果您不需要颜色,则下一个代码段适合您.它基本上将标签扩展添加到BIOS Teletype功能.
; 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
Run Code Online (Sandbox Code Playgroud)
大多数时候,一点颜色会产生奇迹.以下代码片段使用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
Run Code Online (Sandbox Code Playgroud)
使用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
Run Code Online (Sandbox Code Playgroud)
1长延迟功能请求:在接收复制计数为零时使光标前进.
2 Retorical,而不是一个实际的问题.
3除非您选择BIOS没有TTY支持的视频模式.例如.在VESA视频模式下,许多BIOS无法滚动.在传统的图形视频模式12h中,我甚至遇到了无法用功能09h写字符的BIOS!
4可以直接在视频存储器中写入,但需要更多努力.