我目前正在编写一个基本的操作系统作为一个学习项目。为此我使用了gcc 4.9.2交叉编译器。 当试图使用存储器映射的I/O I偶然发现C指针(或可能存储器映射I/O),我无法理解的行为。 当通过下面的代码直接访问I/O存储器,I得到预期的结果,这是一个“AB”在黑色背景上的浅灰色字体的左上角。奇怪的行为映射I/O
*((uint16_t *)0xB8000) = 0x0741;
*((uint16_t *)0xB8002) = 0x0742;
但是试图通过使用偏移添加2基地址来操纵存储器当结果没有作为在第二但在第三位置预期的“A”。
*((uint16_t *)0xB8000 + 2) = 0x0741;
添加1而不是2打印第二个位置的字母,但我不明白为什么。由于每个字母(在MMIO中)由2个字节的数据组成,因此我认为我需要将我写入的内存地址增加2,以便为下一个字符。 (正如我在第一次做直接写入0xB8002) 为了尝试和理解这种行为,我做了一个单独的C程序的一些测试,但无法复制这种行为: (注:此代码被编译使用普通的gcc 4.8 0.2)
#include <stdint.h>
#include <stdio.h>
void main(void) {
printf("0xB8000 + 1 = %x\n", 0xB8000 + 1);
printf("&(*(uint16_t *)(0xB8000 + 1)) = %x\n", (uint32_t)&(*(uint16_t *)(0xB8000 + 1)));
}
这个程序产生的输出如下:
0xB8000 + 1 = b8001
&(*(uint16_t *)(0xB8000 + 1)) = b8001
我认为我缺少某种C指针的行为,这将导致保理在由写入的数据的大小一份声明。这是这种情况还是我有忽略的另一个原因?
问候,Kenshooak
你可能会受益于重新读指针运算基础(总是由基本型缩放)。或者,也许运算符优先级(强制转换优先级高于“+”)。 – Deduplicator 2015-02-11 18:23:34
此外,您可能需要使用'volatile'这里,以确保编译器不自作聪明,优化作业了。 – 2015-02-11 18:49:49