上述所有功能在它们完成的功能上都是独一无二的,但是
起初,丰富度似乎有些夸张。
然后选择哪个功能完全取决于你是什么类型的程序
写作。基本上可以在控制台应用程序和完整的应用程序之间进行选择
屏幕应用程序。 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 输出函数。
如果您不需要颜色,那么下一个代码 sn-p 适合您。它基本上
为 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
大多数时候,一点颜色会产生奇迹。以下代码 sn-ps 使用
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 可以直接在视频内存中写入,但需要更多
努力。