字符读取在图形模式下不起作用

Character reading does not work in graphical mode

我想用 ah=8 int 10h 中断读取一个字符及其属性。

它适用于文本模式,但不适用于图形模式(16 色 640 x 480)。

mov ax,0012h
int 10h       ;graphical mode
int 10h

mov ah,0Ah
mov al,'1'
mov cx,200    ;printing '1' 200 times
mov bx,0
int 10h

mov ah,2
mov dx,0      ;moving cursor to (0,0)
mov bx,0
int 10h

mov bh,0
mov ah,8      ;reading the character
int 10h

代码必须给出 AH=07h & AL=31h.

但是这段代码总是给出 AH=07h & AL=00h.

那么如何在图形模式下使用此方法?

问题简述

  • 写入冗余int 10h
  • 请求的复制计数太大
  • 黑底黑字输出
  • 解释随机寄存器内容

解释

...写一个多余的int 10h

mov ax,0012h
int 10h       ;graphical mode
int 10h

调用 api 函数而不明确指定函数编号从来都不是一个好主意。您可能认为在这个例子中 AX 寄存器仍然保存 0012h(因为功能 00h 被记录为 return 没有),但情况并非总是如此。
我不知道你为什么写第二个int 10h。也许您已经删除了一些额外的说明,而只是忘了删除这个。可能发生...

...请求的复制计数太大

来自我的 BIOS.WriteCharacterOnly 0Ah 的 VGA 程序员指南:

In the graphics modes, the number of times to replicate the character, is limited to the number of remaining character positions to the right of the cursor position until the end of the line.

您的程序将复制计数指定为 200,这比屏幕上可用的 80 列要多得多。要求太多会导致不可预测的行为。
您上一个问题中的 已经显示了这个问题。仔细看图片的左上角

下面是我的计算机 [1] 当我请求复制计数为 81 时显示的内容。在正常显示 80 个字符后,函数换行到屏幕的左边缘而且还下降了单个扫描线(为 1 个像素)!现在您可以看到屏幕左上角的 8x16 字符框不再包含 BIOS 函数 08h 可以识别为有效 ASCII 字符的位模式,因此函数 08h 将 return 和 AL=0

        x=0    x=7
        |      |
       .........................................
y=0 -  .                                        
       .                                        
       .           **      **      **      **   
       .   **     ***     ***     ***     ***   
       .  ***    ****    ****    ****    ****   
       . ****      **      **      **      **   
       .   **      **      **      **      **   
       .   **      **      **      **      **   
       .   **      **      **      **      **   
       .   **      **      **      **      **   
       .   **      **      **      **      **   
       .   **    ******  ******  ******  ****** 
       . ******                                 
       .                                        
       .                                        
y=15 - .                                        

有关 BIOS 之间可能的实现差异,请参阅 。是一个聪明的程序员,确保他的程序在各种机器上都能正常运行。

...在黑色背景上输出黑色字符

当您调用 BIOS 函数 0Ah WriteCharacterOnly 时,'Only' 仅适用于字母数字视频模式。在图形模式中,BL 寄存器中的值用于字符颜色。您的程序传递 0(黑色)作为字符颜色,BIOS 将在黑色背景上使用它。这是无法从屏幕上读取内容的另一个原因。

...解释随机寄存器内容

来自我的 BIOS.ReadAttributeCharacterPair 08h 的 VGA 程序员指南:

No attribute code is returned when the display is in one of the graphics modes.

您的程序处于图形模式(16 色 640x480)。您不应解释 AH 寄存器中的值。它是那里碰巧的任何东西,所以把它当作垃圾对待。在你的电脑上这个寄存器是 7,在我的 [1] 上是 5.

试试这个

您不需要将光标移动到屏幕的左上角,因为光标位置未被函数 0Ah 修改。

mov     ax, 0012h  ; BIOS.SetVideoMode 16-color 640x480
int     10h
mov     cx, 80     ; Replication count
mov     bx, 000Eh  ; Display page 0, character color Yellow
mov     ax, 0A31h  ; BIOS.WriteCharacter(Only)
int     10h
mov     bh, 0      ; Display page 0
mov     ah, 08h    ; BIOS.Read(Attribute)Character(Pair)
int     10h        ; -> AL=31h

[1] Phoenix TrustedCore v1.23 VGA BIOS 1264