Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 在0x000B8000处写入内存映射VGA不会';t打印字符_Assembly_Nasm_X86 16_Bootloader - Fatal编程技术网

Assembly 在0x000B8000处写入内存映射VGA不会';t打印字符

Assembly 在0x000B8000处写入内存映射VGA不会';t打印字符,assembly,nasm,x86-16,bootloader,Assembly,Nasm,X86 16,Bootloader,如果我使用: mov ah, 0x00 mov al, 0x03 int 0x10 要设置视频模式,请执行以下操作: mov dword [0xb8000], 0x0769 要将字符打印到VGA缓冲区,它什么都不做 我从网站上得到的信息是否太旧了?或者我做错了什么?实模式下的偏移量限制为0xFFFF。这不是一个我们熟悉和喜欢的平面32位地址空间。使用NASM 2.14.02组装代码会生成此机器代码(显示了NDISAM的分解): 如果您使用的NASM版本或任何汇编程序没有警告您犯了这个错误,请

如果我使用:

mov ah, 0x00
mov al, 0x03
int 0x10
要设置视频模式,请执行以下操作:

mov dword [0xb8000], 0x0769
要将字符打印到VGA缓冲区,它什么都不做


我从网站上得到的信息是否太旧了?或者我做错了什么?

实模式下的偏移量限制为0xFFFF。这不是一个我们熟悉和喜欢的平面32位地址空间。使用NASM 2.14.02组装代码会生成此机器代码(显示了NDISAM的分解):

如果您使用的NASM版本或任何汇编程序没有警告您犯了这个错误,请更新它或使用它确实具有的警告选项


你该怎么办 相反,将ES设置为0xB800并将其用作段:

mov ax, 0xb800
mov es, ax
mov word [es: 0], 0x0769
另一方面,文本模式下的单个屏幕字符对应于视频内存中的单词,而不是DWORD。一个字节用于字符,另一个字节用于属性


如果您试图覆盖地址大小而不是操作数大小,请使用带有地址大小前缀的DWORD地址:这是可能的,但不会达到您的目的。段限制仍然是64k。但是为了记录在案,NASM语法是

mov  word [dword 0xb8000], 0x0769      ; will #GP fault because of segment limit
; 67 C7 05 00800B00 6907

我想您是在DOS或其他环境下以实模式编程的。请注意,由于分段处于活动状态,所以不能仅线性寻址内存。您必须形成一个合适的段/偏移对(例如,
b800:0000
),用段加载段寄存器,然后从引用适当段寄存器的地址加载。应该注意的是,根据另一条注释中的OP,
int 0x10
部分是在实模式下完成的,用于切换视频模式,以及在写入视频内存时进入保护模式后的某个时间点。您是在实硬件上还是在实PC上进行测试?如果在真正的硬件上失败,您可能会遇到不再支持将字符写入0xb8000以呈现文本的硬件(尽管它将通过int 10h BIOS调用工作)。如果在模拟器上失败,则可能是您如何设置保护模式的问题。@Michael,我从未遇到过任何不支持此功能的硬件。@prl:我有过,其他的也有过。我们已经在OSDev论坛上讨论过这种硬件。这样的硬件是比较新的。硬件使用帧缓冲区显示文本。帧缓冲区实际上不是0xb8000。如果你写信到那个地方,什么也不会发生。如果使用BIOS(由某些CSM提供),将显示文本,因为其中一些BIOS通过将字体写入帧缓冲区来模拟图形字符。我假设汇编程序生成
67
地址大小覆盖,并使用32位寻址模式。这并不是说会提升段限制。@fuz:如果在实模式下执行类似操作(使用32位地址超过64 KiB段限制),则会出现一般保护故障;而且(不幸的是)许多计算机中的BIOS都会假设它是“IRQ 5”,不做任何有用的事情,然后返回导致异常的指令(这将导致另一个异常),导致无限循环(鉴于大多数初学者使用“永远循环,因为我还没有写更多的代码”使他们的启动代码停止。谢谢它工作了,除了应该是mov字[es:0],0x0769。至少在NASM语法中。@fuz:我用NASM试过,因为OP使用的是NASM语法:我得到了
66 C7 06 0080 6907000 mov dword[0x8000],0x769
,并且NASM还打印了
警告:word数据超出边界[-w+数字溢出]
。可能旧的NASM没有默认启用该警告,或者OP忽略了该警告…@user123:我用NASM标记了您的问题,并将此答案从MASM更改为NASM语法。(
word ptr
是MASM风格,就像GNU
。英特尔语法和实际的MASM一样)。我还添加了一些东西,如果Seva需要,可以作为单独的答案。最重要的是,不要忽略汇编程序警告。如果NASM没有就此发出警告,启用
-Wall
,或者升级到更好的NASM版本(如果这还不够)。
mov  word [dword 0xb8000], 0x0769      ; will #GP fault because of segment limit
; 67 C7 05 00800B00 6907