【问题标题】:Something strange with pointer to video memory (0xB8000) [duplicate]指向视频内存的指针(0xB8000)有些奇怪[重复]
【发布时间】:2019-07-04 18:21:27
【问题描述】:

我正在编写一个操作系统。我在 RAM (0xb8000) 中创建了指向视频区域的指针。但是我在写入屏幕时遇到了一些问题。

为了使它起作用(只是写字母),我必须以 1 的偏移量写入内存(如mem[1] = charmem[2] = colour)。这很好用。但是当我需要实现滚动时,我必须从内存的一部分复制到另一部分。在这里我遇到了问题。我无法从记忆中得到一个字符。而且这个偏移量看起来很奇怪,但是没有它就行不通。

void main() {
    volatile unsigned char* mem = 0xB8000;
    mem[0] = 'X';
    mem[1] = 0xf0; // black on white
    mem[2] = 'Z';
    mem[3] = 0xf0; // black on white
    mem[4] = mem[2]; // this line delete all prev letters from display (like shift them out of screen)
    mem[4] = 0xf0;
}

当我在没有mem[4] = mem[2]; 行的情况下启动它时,它可以正常工作。但是通过这一行,我得到了非常奇怪的结果,没有所有 prev 字母(X 和 Z)

这些是我在它不起作用时看到的结果:

当我自己打印X 时会发生这种情况。它似乎工作:

mem[2] = 'Z' 导致X 的颜色不同。并进一步修改(如mem[4] = 'Z')从屏幕上删除所有这些字符

【问题讨论】:

  • 重复是关于为一种架构生成代码但在另一种架构中运行代码。我相信在这个问题中观察到的输出很可能是因为您将代码编译为 64 位,然后在 32 位保护模式下运行它。 64 位代码无法在 32 位代码中正常运行。它可能看起来在运行,但它会做一些不寻常的事情。在操作系统开发中,它通常在写入显示器时以可观察的方式表现出来。您看到的屏幕异常非常能说明这一点。另一个问题有一些解决方案的答案。

标签: c x86 osdev


【解决方案1】:

this article 中所述,文本模式内存为屏幕上的每个字符占用两个字节。第一个是ASCII码字节,另一个是属性字节。

如果您尝试在屏幕上打印“XZZ”,您的代码应如下所示:

void main()
{
  volatile unsigned char* mem = 0xB8000;
  mem[0] = 'X';
  mem[1] = 0xf0; // black on white
  mem[2] = 'Z';
  mem[3] = 0xf0; // black on white
  mem[4] = mem[2];
  mem[5] = 0xf0; // black on white
}

当然,要使其正常工作,您需要确保编译为 32 位,就像 cmets 中建议的 @@MichaelPetch 一样。

【讨论】:

  • 显存是读/写的
  • 如果您只向 mem[0] 和 mem[2] 写入一个字符而不更改视频属性,则字符将显示,但使用的属性将是之前与该屏幕单元相关联的任何内容。跨度>
  • 使用volatile memmem[4] = 'Z'mem[4] = mem[2] 更有效。 IDK 为什么你想强制它读回存储而不是只做两个相同值的存储。特别是因为VGA内存经常映射UC或WC(不可缓存或不可缓存+写组合),所以我认为不会发生存储转发。您可能不需要需要volatile,因为编译器无法证明没有其他东西具有指向该内存的指针。但是,如果您不关心代码大小,请确保它不会受到伤害。 (对于某些编译器volatile 可能会阻止存储合并为 DWORD 存储)
  • @PeterCordes :在问题中,他提到他将致力于滚动。我怀疑mem[4] = mem[2] 是试图将内存中的数据从一个地方复制到另一个地方,作为创建正确滚动功能的实验。
  • @MichaelPetch:正确的滚动功能;我想要 RAM 中的缓冲区,以便您可以从 RAM 复制到 VRAM(并避免从 VRAM 复制到 VRAM,并避免从 VRAM 读取)。请注意,RAM 中的缓冲区可以(并且通常是)大得多 - 例如可能足够 1000 行(而不是只有 25 行),以便以后用户可以使用(例如)“shift+page up”来查看以“阅读速度太快”的方式从屏幕顶部滚动的所有重要内容在启动期间”的方式。这也是支持图形模式的良好一步。
猜你喜欢
  • 2020-02-26
  • 2018-11-29
  • 1970-01-01
  • 1970-01-01
  • 2010-10-27
  • 2013-03-31
  • 2012-07-12
  • 1970-01-01
相关资源
最近更新 更多