控制C中存储器映射寄存器的读写访问宽度

我正在使用基于x86的内核来操作32位内存映射寄存器.仅当CPU对该寄存器产生32位宽的读写操作时,我的硬件才能正常工作.寄存器在32位地址上对齐,并且不能以字节粒度进行寻址.

我该怎么做才能保证我的C(或C99)编译器在所有情况下都只能生成完整的32位宽读写?

例如,如果我执行这样的读 – 修改 – 写操作:

volatile uint32_t* p_reg = 0xCAFE0000;
*p_reg |= 0x01;

我不希望编译器明智地知道只有底部字节发生变化并产生8位宽的读/写.由于机器代码在x86上的8位操作通常更密集,我害怕不必要的优化.一般情况下禁用优化不是一种选择.

—–编辑——-
一篇有趣且非常相关的论文:http://www.cs.utah.edu/~regehr/papers/emsoft08-preprint.pdf

解决方法

您的疑虑由挥发性限定符涵盖.

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.

5.1.2.3“程序执行”(除其他外)说:

In the abstract machine,all expressions are evaluated as specified by the semantics.

接下来是一个通常称为“as-if”规则的句子,如果最终结果相同,则允许实现不遵循抽象机器语义:

An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced (including any caused by calling a function or accessing a volatile object).

但是,6.7.3 / 6基本上表示表达式中使用的volatile限定类型不能应用“as-if”规则 – 必须遵循实际的抽象机器语义.因此,如果取消引用指向易失性32位类型的指针,则必须读取或写入完整的32位值(取决于操作).

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...