在没有 int 10h 的情况下以实模式显示字符?
Display characters in real mode without int 10h?
网络上的某些程序似乎甚至不使用 int
指令就可以完成相同的工作,例如直接写入 bx800
。在这种情况下,BIOS 究竟如何知道是否应将某些文本写入控制台?是否保证初始中断发生?如果是这样,那么确切的时间和执行相同工作的等效装配线(或中断向量和 ah
的组合)是什么?
据我了解,您在向屏幕写入内容时遇到了问题。在实模式下,您根本无法真正访问任何中断。您只能写入显存。这是我快速为您输入的一些代码。希望这有效
mov edi, 0xB8000 ; This will point to the location in ram (b8000 = video mem.)
mov BYTE [edi], 'H' ; First we declar we are moving a byte, then we move 'H' into video memory.
mov BYTE [edi+1], 0Fh ; The second byte is always color. This is White on black
mov BYTE [edi+2], 'i' ; Next print the i
mov BYTE [edi+3], 0Fh
这里我们可以看到,我们首先将edi(内存指针)移动到显存中的位置。 \
BIOS 服务用于抽象硬件。
如果您对底层视频卡有足够的了解,您可以直接对其进行编程。
VGA 已被广泛记录 [1]
[2] [3],虽然这个话题并不容易,而且由于普遍缺乏适当的介绍,学习曲线相当陡峭。
介绍与本站点的答案无关,但可以提供关于为什么可以绕过 BIOS 的简短版本。
VGA 卡有一个内部存储器,可以循环读取(绘图是一项循环业务)以生成模拟信号来驱动 CRT compatible 显示器。
如果我们知道如何将正确的数据放入该内存中,我们将能够绘制一个字符。
CPU的地址space中并非所有地址都被系统内存(子系统)回收,范围0xb8000 - 0xbffff
分配给VGA卡内存-写入该范围会将数据放入卡的内部存储器中。
知道如何将一些数据放入卡的内存中,我们还必须知道要放入什么。
幸运的是 VGA 支持 text modes that allow the programmer to specify a character code instead of drawing each glyph 逐像素。
每个代码(用行话来说,code point - which coincide with the code unit for the encoding used) is associated with a glyph by the means of the charset setup by IBM at the time (CP437)。
除了代码点,程序员还可以指定 character attributes,例如前景色和背景色。
例如,启用文本模式后,要在第一行第一列绘制蓝色 A 只需写:
mov WORD [es:0], 0941h ;Assuming ES = 0b800h
;09 = Attributes (Blue on black)
;41h = Code point of the glyph A
每个字符占用两个字节(一个字),第一个是代码点,第二个是属性。
由于 x86 endianness 41h(代码点)将在地址 0 处结束,而属性将在地址 1 处。
内部情况比较复杂:参见memory layout和odd/even模式。
这就是有效的硬件编程:将数据移动到不同语义的上下文中。
网络上的某些程序似乎甚至不使用 int
指令就可以完成相同的工作,例如直接写入 bx800
。在这种情况下,BIOS 究竟如何知道是否应将某些文本写入控制台?是否保证初始中断发生?如果是这样,那么确切的时间和执行相同工作的等效装配线(或中断向量和 ah
的组合)是什么?
据我了解,您在向屏幕写入内容时遇到了问题。在实模式下,您根本无法真正访问任何中断。您只能写入显存。这是我快速为您输入的一些代码。希望这有效
mov edi, 0xB8000 ; This will point to the location in ram (b8000 = video mem.)
mov BYTE [edi], 'H' ; First we declar we are moving a byte, then we move 'H' into video memory.
mov BYTE [edi+1], 0Fh ; The second byte is always color. This is White on black
mov BYTE [edi+2], 'i' ; Next print the i
mov BYTE [edi+3], 0Fh
这里我们可以看到,我们首先将edi(内存指针)移动到显存中的位置。 \
BIOS 服务用于抽象硬件。
如果您对底层视频卡有足够的了解,您可以直接对其进行编程。
VGA 已被广泛记录 [1]
[2] [3],虽然这个话题并不容易,而且由于普遍缺乏适当的介绍,学习曲线相当陡峭。
介绍与本站点的答案无关,但可以提供关于为什么可以绕过 BIOS 的简短版本。
VGA 卡有一个内部存储器,可以循环读取(绘图是一项循环业务)以生成模拟信号来驱动 CRT compatible 显示器。
如果我们知道如何将正确的数据放入该内存中,我们将能够绘制一个字符。
CPU的地址space中并非所有地址都被系统内存(子系统)回收,范围0xb8000 - 0xbffff
分配给VGA卡内存-写入该范围会将数据放入卡的内部存储器中。
知道如何将一些数据放入卡的内存中,我们还必须知道要放入什么。
幸运的是 VGA 支持 text modes that allow the programmer to specify a character code instead of drawing each glyph 逐像素。
每个代码(用行话来说,code point - which coincide with the code unit for the encoding used) is associated with a glyph by the means of the charset setup by IBM at the time (CP437)。
除了代码点,程序员还可以指定 character attributes,例如前景色和背景色。
例如,启用文本模式后,要在第一行第一列绘制蓝色 A 只需写:
mov WORD [es:0], 0941h ;Assuming ES = 0b800h
;09 = Attributes (Blue on black)
;41h = Code point of the glyph A
每个字符占用两个字节(一个字),第一个是代码点,第二个是属性。
由于 x86 endianness 41h(代码点)将在地址 0 处结束,而属性将在地址 1 处。
内部情况比较复杂:参见memory layout和odd/even模式。
这就是有效的硬件编程:将数据移动到不同语义的上下文中。