【发布时间】: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 的一部分。