【发布时间】:2025-12-13 05:05:01
【问题描述】:
我意识到在保护模式下,可以通过修改内存位置 0xb8000 等来使用内存映射 I/O 来打印字母...... 我们可以在 16 位实模式下做到这一点吗? (使用分段访问位置,然后进行修改)
这是我的汇编代码...
[bits 16]
mov ax,0xb800
mov ds,ax #This is the segment register that should hopefully give me 0xb8000
mov byte[ds:0x0000],'X'
mov byte[ds:0x0001],0x0f
times 510-($ -$$) db 0
dw 0xaa55
顺便说一句,这不起作用..
[编辑] 结果我最后需要 jmp $ 来防止任何随机代码执行并且代码按预期工作
【问题讨论】:
-
这只是好奇
-
是的,这样的东西应该可以在引导加载程序中使用。 (顺便说一句,它不完全是 MMIO;您正在写入设备内存,而不是写入每次读取或写入都有副作用的 IO 寄存器)。您是否尝试遵循写入 VGA 内存的工作示例? VGA 和 bootloader 标签中应该还有其他的;使用 SO 的搜索。另外,“不工作”怎么办?在 BOCHS 调试器中单步执行会发生什么? IDK 如果您在代码之后没有包含
hlt/jmp循环很重要,那么它会继续以add [mem], al执行00 00字节(使用一些寻址模式,IDK 16 位 modrm) -
你可能想在那段代码之后放置一个
jmp $无限循环,我不知道00、aa和55的操作但它甚至有可能会在引导扇区的末尾运行并执行任意代码 - 这不太可能结束。 -
而且,是的,这实际上是当时为提高速度而采取的方式,只是后来才出现可移植性问题。粗略一瞥,依靠可能受损的记忆而不是研究:-),你所拥有的应该可以正常工作。请记住,地址是用于 CGA 的,我相信 MDA 和 EGA 使用完全不同的地址。由于您的问题上有一个 VGA 标签,您可能需要先进行一些初始化,VGA 具有决定模式及其在地址空间中的位置的寄存器。
-
您可能还想看看我们的复古计算姊妹网站retrocomputing.stackexchange.com。他们可能在该主题上更多知识渊博。
标签: assembly x86-16 bootloader osdev vga