Assembly 以VGA模式13小时写入视频存储器

Assembly 以VGA模式13小时写入视频存储器,assembly,Assembly,我正在使用NASM学习x86汇编,在linux上用qemu运行我的代码。 我试图在屏幕上画一个像素 为什么会这样 mov bx,0xA000 mov byte [bx],0x0A 似乎什么都没做,但是 mov bx,0xA000 mov es,bx mov byte [es:di],0x0A 你能画一个像素吗 第二个问题:为什么我必须使用[es:di]而不仅仅是[es]?在实模式下,用于读取和写入的地址由一个段和一个偏移量组成,从中读取或写入的实际地址计算为段*

我正在使用NASM学习x86汇编,在linux上用qemu运行我的代码。 我试图在屏幕上画一个像素

为什么会这样

mov     bx,0xA000 
mov byte [bx],0x0A
似乎什么都没做,但是

mov     bx,0xA000 
mov     es,bx 
mov byte [es:di],0x0A
你能画一个像素吗


第二个问题:为什么我必须使用[es:di]而不仅仅是[es]?

在实模式下,用于读取和写入的地址由一个段和一个偏移量组成,从中读取或写入的实际地址计算为
段*16+偏移量

注:在文件等方面;段和偏移量通常是由冒号连接的两个数字组成(如0x1234:0x5678,其中0x1234是段,0x5678是偏移量)

对于0x0000:0xA000,实际地址为0x0000A000。该地址通常对应于RAM

对于0xA000:0x0000,实际地址为0x000A0000。这就是传统VGA显示存储区的位置(当视频卡模拟古代VGA的320*200视频模式时使用)

所有读写操作都使用段寄存器,如果您没有明确指定一个(例如,
mov[es:di],ax
),则CPU使用默认/隐含段寄存器,通常为
DS
(除非
SP
BP
用于地址的偏移部分,使
SS
成为默认/隐含段,或其指令提取总是使用
CS
)。这意味着
mov[di],ax
的作用与
mov[ds:di],ax
相同


偏移部分总是显式的,CPU不支持(例如,“默认偏移量为0x0000”。这意味着您不能执行
mov[es],ax
,因为没有偏移量(也无法对指令进行编码),您必须执行类似
mov[es:0x0000]的操作,ax

许多旧的汇编指南不再适用。保护模式计算阻止直接硬件访问,例如在现代操作系统上向VGA缓冲区移动位或从VGA缓冲区移动位。如果您运行的是旧版本的DOS,您仍然可以使其正常工作。(A)这是因为您试图写入程序正在运行的64kb内存块(称为段)中的位置0xA。假设您的段为0x1000,您将尝试写入0x1000:0x000A(分段地址),即(0x1000@DavidC.Rankin:只要您的GDT设置为可以访问较低1mb的RAM,那么在保护模式下,您肯定可以写入相同的视频位置。我假设,虽然我们正在处理一个有自己操作系统的纯金属环境。如果我们是Linux之类的用户应用程序,那么直接使用硬件如果没有内核的特殊许可,将不允许重新访问。