【问题标题】:Video memory access and postfix incrementation显存访问和后缀增量
【发布时间】:2015-08-27 08:38:05
【问题描述】:

我在内存访问和 postix 增量方面遇到了一些问题:/
我需要在启动时访问视频内存,因此,我创建了一个指向 0xB8000 地址的指针,然后增加指针以访问下一个位置。

基本上,代码是:

volatile char *p = (volatile char *)0xB8000;

for (int i = 0; i < 5; ++i)
    *(p++) = 'A';

这样,p 指向正确的内存地址,每次访问后,它都会递增(我知道,每个显示的字符有 2 个字节,但这不是问题)。

但这不起作用,没有字符显示。它什么也不显示。但是,如果我将增量​​更改为这样的前缀,它会起作用,我可以在屏幕上看到字符!

volatile char *p = (volatile char *)0xB8000;

for (int i = 0; i < 5; ++i)
    *(++p) = 'A'

所以,我检查了汇编代码:

; Postfix
mov ecx, DWORD PTR _p$[ebp]
mov BYTE PTR [ecx], 65       ; 'A' character
mov edx, DWORD PTR _p$[ebp]
add edx, 1
mov DWORD PTR _p$[ebp], edx

; Prefix
mov ecx, DWORD PTR _p$[ebp]
add ecx, 1
mov DWORD PTR _p$[ebp], ecx
mov edx, DWORD PTR _p$[ebp]
mov BYTE PTR [edx], 65       ; 'A' character

我看不出区别。顺便说一句,我可以使用前缀增量,但我想了解后缀是否不起作用:/

汇编代码来自 Visual C++ 编译器,我没有任何 GCC 工作:/

EDIT :我知道前缀和后缀递增之间的区别,并且我看到了这里的汇编代码之间的区别。但是 IMO,这些差异都不会导致屏幕上出现非打印字符。
关于属性字节:我知道我应该正确设置它。我会保留一个简单的汇编代码示例,但实际上,随着递增,属性字符始终设置为“A”,这会导致红色背景上的蓝色字母。

谢谢你:)

【问题讨论】:

  • ++p 递增,然后读/写。 p++ 读/写,然后递增。这是命令。如果我做 int a = 4;诠释 b = ++a;那么 b 将是 5。如果我这样做 int b = a++;而 b 将是 4。
  • 为什么你认为没有区别?仔细阅读你的汇编代码是有区别的。
  • 显存每个字符使用两个字节,一个用于选择字形,一个用于颜色。如果其中任何一个未设置,则会出现空白字符或 黑色 字符。两者都是隐形的!
  • "每个字符显示 2 个字节,但这不是问题"。你确定这不是问题吗?因为不同之处在于您不为后增量情况下的第一个字符写入属性字节(而是为第三个字符写入属性字节)。
  • @enhzflep minuszerodegrees.net/oa/…(IBM CGA 技术参考),明确指出:A ROS character generator is used with 8K bytes of storage that cannot be read from or written to under program control.。所以它显然不是 BIOS 的一部分。

标签: c pointers memory


【解决方案1】:

经过几次测试,我找到了这个错误的可能原因,它是关于.rodata部分没有正确链接,所以现在更好了。

有关更多详细信息,我会按照OSDev Tutorial 上的一些说明进行操作;)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-08
    • 2012-10-03
    • 2017-12-12
    • 2014-08-11
    • 1970-01-01
    • 1970-01-01
    • 2011-03-12
    相关资源
    最近更新 更多