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 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)