我想用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
。
那么如何在图形模式下使用此方法?
答案 0 :(得分:2)
int 10h
int 10h
mov ax,0012h int 10h ;graphical mode int 10h
在没有显式指定函数编号的情况下调用api函数绝不是一个好主意。您可能会认为,在此示例中,AX
寄存器仍然保留0012h(因为文档中记录了功能00h不会返回任何内容),但不一定总是这样。
我不知道你为什么写第二个int 10h
。也许您已经删除了一些额外的说明,而只是忘了删除此说明。会发生...
摘自《我的BIOS VGA程序员指南》。WriteCharacterOnly0Ah:
在图形模式下,复制字符的次数被限制为光标位置右侧直到行尾的剩余字符位置的数量。
您的程序将复制计数指定为200,这比屏幕上可用的80列要多得多。请求过多会导致无法预测的行为。
您上一个问题中的screenshot for emu8086已显示此问题。仔细看图片的左上角。
下面是我的计算机 [1] 所显示的,当我请求复制计数为81时。正常显示80个字符后,该函数环绕在屏幕的左侧下降一条扫描线(为1像素)!现在,您可以看到屏幕左上角的8x16字符框不再包含BIOS模式08h可以识别为有效ASCII字符的位模式,因此功能08h将返回AL=0
。
x=0 x=7
| |
.........................................
y=0 - .
.
. ** ** ** **
. ** *** *** *** ***
. *** **** **** **** ****
. **** ** ** ** **
. ** ** ** ** **
. ** ** ** ** **
. ** ** ** ** **
. ** ** ** ** **
. ** ** ** ** **
. ** ****** ****** ****** ******
. ******
.
.
y=15 - .
有关BIOS之间可能的实现差异,请参见this comment by Michael Petch。这是一个明智的程序员,可以确保他的程序在各种机器上都能正常运行。
当您调用BIOS函数0Ah WriteCharacterOnly 时,“ Only ”仅适用于字母数字视频模式。在图形模式下,BL
寄存器中的值用于字符颜色。您的程序将传递0(黑色),因为字符颜色和BIOS将在黑色背景上使用该颜色。这是无法从屏幕上读取某些内容的另一个原因。
摘自《我的BIOS VGA程序员指南》 .ReadAttributeCharacterPair 08h:
当显示处于其中一种图形模式时,不返回任何属性代码。
您的程序处于图形模式(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