使用DOS或BIOS显示字符

时间:2017-06-25 13:48:02

标签: assembly x86 dos bios

浏览Ralph Brown's interrupt list,  我发现有很多不同的方法可以将文本字符输出到屏幕上。

ROM BIOS API提供以下功能:

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

DOS API提供以下功能:

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

这些功能有什么作用?我怎么称呼他们?我如何在它们之间做出选择?

1 个答案:

答案 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

总结

  • 对于控制台应用程序, WriteStringDOS WriteStringBIOS 程序绰绰有余 3
  • 对于全屏应用程序 WriteStringWithAttributeTVM WriteStringWithAttributeGVM 程序同等地提供 3 4
  • DOS和BIOS都没有足够的设备来处理图形视频 模式。编写自己的图形例程(不是一个简单的任务!)或使用 第三方图形库。

1 长时间延迟功能请求:使光标前进  接收复制计数为零 2 Retorical,而非实际问题。
3 除非您选择BIOS没有TTY的视频模式 支持。例如。许多BIOS在VESA视频模式下无法滚动。我甚至来了 在传统图形视频模式12h上,无法用功能09h写入字符的BIOS! 4 可以直接在视频内存中写入,但需要更多 努力。