如何在x86程序集中以受保护模式在屏幕上绘制像素?

ali*_*ali 15 memory video x86 assembly pixel

我正在创建一个小的bootloader +内核,直到现在我设法读取磁盘,加载第二个扇区,加载GDT,打开A20并启用pmode.

我跳转到32位功能,在屏幕上显示一个字符,使用视频内存作为文本内容(0x000B0000 - 0x000B7777)

pusha
mov edi, 0xB8000
mov bl, '.'
mov dl, bl
mov dh, 63
mov word [edi], dx
popa
Run Code Online (Sandbox Code Playgroud)

现在,我想再进一步在屏幕上绘制一个像素.正如我在某些网站上看到的那样,如果我想使用VGA的图形模式,我必须在0x000A0000位置写入像素.是对的吗?

现在,单个像素的格式是什么?对于单个字符,您需要ASCII代码和属性,但是您需要定义一个像素(如果它的工作方式与文本模式相同)?

Ant*_*nko 19

不幸的是,它稍微远一点.

写入视频内存的规则取决于图形模式.在传统的视频模式中,VGA模式320x200(8bpp)是唯一一个视频存储器像普通存储器一样工作的模式:从0xA000:0000(或0xA0000线性)开始,向视频缓冲区写入一个对应于您想要的像素的字节, 就这样.

对于其他VGA(SVGA前)模式,规则更复杂:当您将一个字节写入视频内存时,您会寻址一组像素,而我忘记的一些VGA寄存器会指定哪些像素的平面更新以及如何使用它们的旧值.它不仅仅是记忆了.

有SVGA模式(从800x600x8bpp开始); 您可以使用VESA Video Bios Extensions以与硬件无关的方式切换到它们.在这些模式下,视频内存的行为与内存类似,每个像素有1,2,3或4个字节,没有类似VGA的8像素组,只需一个字节访问即可触摸.问题是实模式视频缓冲区不再足够大以解决整个屏幕问题.

VESA VBE 1.2通过提供函数来修改解决了这个问题存储器窗口碱:在任何特定时刻,在线性0xA0000段被寻址视频存储器的64Kb的区,但可以控制整个的64Kb的帧缓冲器可在此地址(基址调整的最小单位,即窗口粒度,取决于硬件,但您可以依赖于在0xA0000处映射N*64Kb偏移的能力.缺点是每次开始使用不同的64Kb块时都需要VBE BIOS调用.

VESA VBE 2.0增加了平面帧缓冲,可在保护模式下的某个高地址处使用(也可以在虚幻模式下).因此,进入视频模式需要VBE BIOS调用,但不能用于绘制像素.

VESA VBE 3.0可能还不够便携,它提供了一种在保护模式下调用VBE功能的方法.(我没有机会尝试它,在我的"装配操作系统"时代不存在).

无论如何,你必须先切换到图形模式.这样做有几种变体:

  • 最简单的方法是在进入保护模式之前使用BIOS调用.使用VBE 2.0,您不需要视频内存窗口调整调用.
  • 另一种方法是创建一个V8086模式环境,这对于BIOS来说已经足够了.最难的部分是将中断转发给实模式中断处理程序.这并不容易,但是当它完成后,您将能够在PM中切换视频模式并使用其他一些BIOS功能(例如,用于磁盘I/O).
  • 另一种方法是使用VESA VBE 3.0保护模式接口.不知道它有多简单或复杂.
  • 真正的绝地方式是挖掘特定视频卡上的信息,通过设置寄存器来切换模式.去过那里,过去为一些Cirrus卡做过 - 在PM中获得大型平板帧缓冲并不太复杂.它是不可移植的,但如果目标是了解机器的内部结构,那么它可能就是您所需要的.

  • 某些 VBE 2/3 BIOS 不支持 LFB。早在 2001 年,我就在一些英特尔芯片上发现了这一点,该芯片结合了内存控制器和视频设备。 (2认同)

nrz*_*nrz 5

这取决于使用的图形模式,并且有很多差异。BIOS VGA 视频模式13h(320x200 8 位/像素)可能是最容易上手的(它是唯一具有 256 色的 BIOS VGA 视频模式,但是您可以通过直接写入显卡端口来创建自己的模式):在 BIOS 视频模式 13h 中,映射到屏幕的视频内存开始于0x0A0000并且它为每个像素连续运行 1 个字节,并且只有 1 个位平面,因此每个坐标的内存地址为0x0A000 + 320*y + x

在实模式下更改为 BIOS 视频模式 13h(320 x 200 8 位/像素):

mov ax,0x13
int 0x10
Run Code Online (Sandbox Code Playgroud)

在保护模式下在左上角(视频模式 13h)绘制像素:

mov edi,0x0A0000
mov al,0x0F      ; the color of the pixel
mov [edi],al
Run Code Online (Sandbox Code Playgroud)

  • 是的当然。`mov ax,13h`、`int 10h` 就是这样做的(在实模式下)。 (2认同)