写入视频内存(0xB8000)和易失性指针
Writing to video memory (0xB8000) & volatile pointer
我正在尝试用 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);
我不应该像unsigned char * volatile video
那样将指针定义为volatile
吗?所以编译器知道地址可以改变?
为什么不呢:
unsigned char * video = 0xB8000;
video[x] = 'A';
volatile
的要点是告诉编译器变量的内容可能会更改或在代码执行之外 产生副作用。正如 standard (C99 6.7.3.6) 所说:
An object that has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects. Therefore any expression referring to such an object shall be evaluated strictly according to the rules of the abstract machine, as described in 5.1.2.3. Furthermore, at every sequence point the value last stored in the object shall agree with that prescribed by the abstract machine, except as modified by the unknown factors mentioned previously. What constitutes an access to an object that has volatile-qualified type is implementation-defined.
这就是为什么你需要告诉编译器变量指向的内存是易变的。但是,更改指针指向的地址不会导致任何副作用,并且不会在代码执行之外自行更改,因此指针本身没有理由易变。如果我们必须将我们希望在某个时候更改的所有变量标记为 volatile
,几乎所有变量都必须这样标记。
我正在尝试用 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);
我不应该像unsigned char * volatile video
那样将指针定义为volatile
吗?所以编译器知道地址可以改变?
为什么不呢:
unsigned char * video = 0xB8000;
video[x] = 'A';
volatile
的要点是告诉编译器变量的内容可能会更改或在代码执行之外 产生副作用。正如 standard (C99 6.7.3.6) 所说:
An object that has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects. Therefore any expression referring to such an object shall be evaluated strictly according to the rules of the abstract machine, as described in 5.1.2.3. Furthermore, at every sequence point the value last stored in the object shall agree with that prescribed by the abstract machine, except as modified by the unknown factors mentioned previously. What constitutes an access to an object that has volatile-qualified type is implementation-defined.
这就是为什么你需要告诉编译器变量指向的内存是易变的。但是,更改指针指向的地址不会导致任何副作用,并且不会在代码执行之外自行更改,因此指针本身没有理由易变。如果我们必须将我们希望在某个时候更改的所有变量标记为 volatile
,几乎所有变量都必须这样标记。