控制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++指针和引用的选择最近在看...
关于vtordisp知多少?我相信不少人看到这篇文章,多半是来自...
那些陌生的C++关键字学过程序语言的人相信对关键字并...
命令行下的树形打印最近在处理代码分析问题时,需要将代码的...
虚函数与虚继承寻踪封装、继承、多态是面向对象语言的三大特...