使用DOS或BIOS显示字符 [英] Displaying characters with DOS or BIOS

查看:138
本文介绍了使用DOS或BIOS显示字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过拉尔夫·布朗的中断列表, 我发现有很多不同的方法可以将文本字符输出到屏幕上.

Looking through Ralph Brown's interrupt list, I discovered that there are many different ways to output text characters to the screen.

ROM BIOS API提供以下功能:

The ROM BIOS API offers these functions:

  • AH = 09h –在光标位置写字符和属性
  • AH = 0Ah –仅在光标位置写字符
  • AH = 0Eh –电传输出
  • AH = 13h –写字符串

DOS API提供以下功能:

The DOS API offers the following functions:

  • AH = 02h –将字符写入标准输出
  • AH = 06h –直接控制台输出
  • AH = 09h –将字符串写入标准输出

这些功能有什么作用?我怎么称呼他们?我该如何选择呢?

What do these functions do? How do I call them? And how do I choose between them?

推荐答案

所有上述功能在完成功能上都是独特的,但是 起初,丰度似乎有些夸张.

All of the forementioned functions are unique in what they accomplish, but at first the abundance does seem somewhat exagerated.

  • 整数21h AH = 02h 将字符写入标准输出
    此功能解释字符代码7(哔声),8(退格键),9(制表符), 10(换行)和13(回车).所有其他字符代码是 已显示.
    退格键是非破坏性的,表示光标将一个位置移动到 留下而不会擦除下面的内容. Backspacing在左边缘停止 屏幕上的
    . 选项卡通过此功能扩展.制表符扩展是替换的过程 ASCII 9除以一系列一个或多个空格(ASCII 32),直到光标到达 列位置是8的倍数.
    换行将光标向下移动一行,如果需要,滚动屏幕.
    回车将光标移动到屏幕的最左侧.

  • Int 21h AH=02h Write Character To Standard Output
    This function interprets the character codes 7 (Beep), 8 (Backspace), 9 (Tab), 10 (Linefeed), and 13 (Carriage return). All other character codes are displayed.
    Backspace is nondestructive meaning that the cursor moves one position to the left without erasing what is underneath. Backspacing stops at the left edge of the screen.
    Tabs are expanded by this function. Tab expansion is the process of replacing ASCII 9 by a series of one or more spaces (ASCII 32) until the cursor reaches a column position that is a multiple of 8.
    Linefeed moves the cursor one line down, scrolling the screen if required.
    Carriage return moves the cursor to the far left of the screen.

Int 21h AH = 06h 直接控制台输出
与功能02h非常相似,但由于它本身不适合一般使用 无法输出字符255.仅供参考,FAT文件名中的合法字符.
似乎完全是为了避免 ctrl C / ctrl 中断检查.

Int 21h AH=06h Direct Console Output
Very similar to function 02h, but not well suited for general use as it is not possible to output character 255. FYI a legal character in FAT filenames.
It would seem that it solely exists to avoid ctrlC/ ctrlBreak checking.

整数21h AH = 09h 将字符串写入标准输出
函数02h的字符串版本,但无法输出字符 36,因为该字符串用作字符串终止符.这是一个主要缺点 由于字符36( $ )不仅是众所周知的货币符号,而且还是 FAT文件名中的合法字符.

Int 21h AH=09h Write String To Standard Output
The string version of function 02h, but with the inability to output character 36 since that one is used as the string terminator. This is a major drawback since character 36 ($) not only is a well-known currency symbol, but also a legal character in FAT filenames.

整数21h AH = 40h 写入文件或设备
与预定义手柄1一起使用时,此功能输出到STDOUT 默认为屏幕.所以这是显示的另一种可能性 人物.但是请注意,它不依赖于字符串终止 字符,而是长度.当然是最完整的输出功能. 它解释需要解释的内容,但不排除某些 字符,并且可以捕获重定向错误,尽管后者涉及使用 Int 24h处理程序 .

Int 21h AH=40h Write To File Or Device
When used with predefined handle 1 this function outputs to STDOUT which defaults to the screen. So here's one more possibility for displaying characters. Note however that it does not rely on a string terminating character but rather a length. Certainly the most complete output function. It interprets what needs to be interpreted, it does not exclude certain characters and it allows to catch redirection errors although the latter involves the use of an Int 24h handler.

整数10h AH = 09h 在光标位置写字符和属性
没有任何字符代码被解释,它们都显示在屏幕上. 在文本模式下,提供的属性字节会同时产生前景和 背景色,但是在图形模式下,您只能获得前景色. 光标位置不变.遗憾! 1

Int 10h AH=09h Write Character And Attribute At Cursor Position
None of the character codes gets interpreted, they're all displayed on screen. In text mode the provided attribute byte produces both foreground- and background colors, but in graphics mode you can only get a foreground color. The cursor position does not change. Pity! 1

整数10h AH = 0Ah 仅在光标位置写入字符
与文本模式下的功能09h相似,但省略了属性字节. 在图形模式下,此功能与功能09h相同.

Int 10h AH=0Ah Write Character Only At Cursor Position
Similar to function 09h in text mode but omitting the attribute byte. In graphics mode this function is identical to function 09h.

整数10h AH = 0Eh 原型输出
此功能解释字符代码7(哔),8(退格), 10(换行)和13(回车).所有其他字符代码是 显示.遗憾的是,此功能无法扩展选项卡!

Int 10h AH=0Eh Teletype Output
This function interprets the character codes 7 (Beep), 8 (Backspace), 10 (Linefeed), and 13 (Carriage return). All other character codes are displayed. Too bad this function does not expand tabs!

整数10h AH = 13h 写入字符串
在某种程度上,这是函数0Eh的字符串版本.但是对于 一般使用缺少制表符扩展肯定是一个限制.
以及为什么有这么多参数? 2

Int 10h AH=13h Write String
To some degree this is the string version of function 0Eh. However for general use the lack of tab expansion is certainly a limitation.
And why so many parameters? 2

然后选择哪个功能完全取决于您使用的是哪种程序 写作.基本上,可以在控制台应用程序和完整应用程序之间进行选择. 屏幕应用程序.诸如CHKDSK.EXE或TREE.COM之类的工具是控制台应用程序. QBASIC.EXE或NE.COM之类的程序是全屏应用程序.

Which function to choose then entirely depends on what kind of program you're writing. Basically there's a choice between a console application and a full screen application. Tools like CHKDSK.EXE or TREE.COM are console applications. Programs like QBASIC.EXE or NE.COM are full screen applications.

控制台应用程序:

  • 不关心使用颜色
  • 以线性方式将其输出写在屏幕上
  • 不妨碍操作系统进行输出重定向的功能
  • 通常执行一项任务
  • 通常在眨眼时就结束

面向屏幕的应用程序:

  • 使用适量的颜色会带来很多好处
  • 在屏幕上徘徊,并在需要的地方写上想要的东西
  • 无需担心输出重定向,因为以上内容很快就可以了 使此类输出不可读
  • 经常执行(太多)任务
  • 继续进行,直到您决定是时候退出
  • benefits greatly from using the right amount of color
  • wanders over the screen and writes what it wants where it wants it
  • needs not to worry about output redirection as the above will soon enough render such output unreadable
  • often performs (too) many tasks
  • goes on until you decide it's time to exit

仅DOS输出功能提供必需/推荐的重定向 能力.输出功能02h非常完美.即使没有自己的错误 报告输出时应何时发生错误(极不可能) 重定向后,默认严重错误消息为取消,重试,失败?" 看起来不太合适. (如果这是一个全屏应用程序, 同样的消息会极大地破坏屏幕.)

Only the DOS output functions offer the required/recommended redirection capability. Output function 02h is perfect. Even though it lacks its own error reporting for when an error (very unlikely) should occur while output is redirected, the default critical error message of "Abort, Retry, Fail?" doesn't look too much out of place. (Had this been a full screen application, the same message would have disrupted the screen enormously.)

; 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

但是有时您会想要显示一个临时项目,例如:

Sometimes however you'll want to display a temporary item like:

  • 某种提示(-更多-",准备好时敲击键..."等)
  • 运行计数器/百分比
  • 进度条

为了避免弄乱任何重定向的输出,最好不要使用DOS 在这些临时项目上输出函数.最好使用 WriteStringBIOS 接下来的代码.

In order to avoid messing up any redirected output, it's best to not use DOS output functions on these temporary items. Better use the WriteStringBIOS code that comes next.

现在输出重定向是您的敌人,因此不要使用任何DOS输出功能. 如果您不需要颜色,那么下一个代码段适合您.基本上 将选项卡扩展添加到BIOS Teletype功能.

Now output redirection is your enemy, so don't use any of the DOS output functions. If you don't need the color then next code snippet is for you. It basically adds tab expansion to the BIOS Teletype function.

; 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输出到 前进光标.一个很好的组合,可以使事情变得简单.

Most of the time a bit of color will work wonders. Following code snippets use BIOS function 09h for outputting the colored character and BIOS function 0Eh to advance the cursor. A good combination that keeps things simple.

在文本视频模式下使用第一个:

Use the first one in text video mode:

; 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拒绝绘制背景颜色.

Use the second one in 16 color graphics video mode. It's a bit more involved since BIOS refuses to draw background colors.

; 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 过程平均提供 3 4 .
  • DOS和BIOS都没有足够的能力来处理图形视频 模式.编写自己的图形例程(而不是琐碎的任务!)或使用 第三方图形库.

  • In summary

    • For a console application the WriteStringDOS and WriteStringBIOS procedures are more than adequate3.
    • For a full screen application the WriteStringWithAttributeTVM and WriteStringWithAttributeGVM procedures equally deliver3 4.
    • Neither DOS nor BIOS are sufficiently equipped to handle the graphics video modes. Either write your own graphics routines (not a trivial task!) or use a 3rd party graphics library.
    • 1 长时间延迟的功能请求:使光标前进 接收到的复制计数为零.
      2 回答性的,不是一个实际的问题.
      3 除非您选择BIOS没有TTY的视频模式 支持.例如.在VESA视频模式下,许多BIOS无法滚动.我什至来了 在无法在旧版图形视频模式12h上写入功能为09h的字符的BIOS上! 4 可以直接在视频内存中写入,但需要更多内容 努力.

      1 Long delayed feature request: Making the cursor advance upon receiving a replication count of zero.
      2 Retorical, not an actual question.
      3 Unless you select a video mode for which the BIOS has no TTY support. eg. Many BIOSes can't scroll when in a VESA video mode. I even came across a BIOS that is unable to write characters with function 09h on the legacy graphics video mode 12h!
      4 Writing directly in the video memory is possible but requires more effort.

      这篇关于使用DOS或BIOS显示字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆