以VGA模式写入视频存储器13h

时间:2015-11-11 04:45:52

标签: 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]?

1 个答案:

答案 0 :(得分:4)

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

注意:在文档中等;段和偏移量通常是写入由冒号连接的2个数字(如0x1234:0x5678,其中0x1234是段,0x5678是偏移量)

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

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

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

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