【发布时间】:2015-08-26 08:35:30
【问题描述】:
我正在尝试用 C 编写自己的小内核,实际上我想编写一个打印函数来显示字符串。因此,我想写入视频内存(0xB8000)。
所以,我是这样尝试的:
unsigned char *video = (unsigned char *)0xB8000;
*video = 'A';
这确实有效,但以下无效:
char x = 0;
unsigned char *video = (unsigned char *)(0xB8000 + x);
*video = 'A';
经过一番研究,我认为原因可能是编译器的优化,OSDev 给了我解决方案:使用volatile 关键字。所以我对这个关键字做了一些研究。 OSDev 建议这样做:
char x = 0;
volatile unsigned char *video = (volatile unsigned char *)(0xB8000 + x);
*video = 'A';
这样,它应该可以工作。编译器假定video 指针指向的值可以改变,然后不对其进行优化。但是,如果以后我想更改它,例如:
video = (volatile unsigned char *)(video + 2);
我不应该将指针定义为volatile,比如unsigned char * volatile video吗?那么编译器知道地址可以改变吗?
【问题讨论】:
-
我不明白没有 volatile 什么是行不通的?
unsigned char *video = (unsigned char *)(0xB8000 + x);。我想问题是x是char而不是int/unsigned。类型可能是问题,而不是非波动性 -
@i486 如果编译器能够推断出
video的内容永远不会被读取,它可能会优化对它的写入。 -
为什么
(unsigned char *)(0xB8000 + x)不会将值写入视频内存而(unsigned char *)0xB8000会这样做?我认为不可能有这样的优化。只有video的值可以保存在 CPU 寄存器中,而不是它的内存位置。 -
我同意这很奇怪,但是在第一种情况下不会发生优化这一事实并不是真的不会在第二种情况下发生的论点案例。
-
请注意,虽然在这里使用
volatile(可能)是有效的,但在将它用于整个内核之前,您应该阅读this。一个更好的方法,而不是声明videovolatile,是将所有需要可变的访问转换为volatile。
标签: c pointers memory volatile