我在AVR32上有一个中断服务路由。我需要从中断状态寄存器中读取以取消中断。然而,我没有使用读取的结果。我宁愿不使用asm指令,但我担心gcc会优化对虚拟变量的读取。正确的方法是什么?
目前我有:
uint32_t tmp = *(volatile uint32_t *)INTERRUPT_STATUS_REG_ADDRESS;tmp也应该是不稳定的吗?我担心如果不使用tmp,gcc会跳过读。
发布于 2014-10-21 07:50:31
通过指针转换到(易失性uint32_t*)来读取中断状态寄存器会告诉编译器,读取这个表达式(指定地址的变量)会产生副作用,因此它总是需要计算这个表达式。
由于tmp变量不易失性,编译器可以自由地将寄存器的值存储到变量中。
我认为C标准(见这里)的第5.1.2.3章有足够的相关性。
此外,第6.7.3章解释:
具有易失性限定类型的对象可以以实现未知的方式进行修改,或者具有其他未知的副作用。因此,任何涉及此类对象的表达式都应严格按照5.1.2.3中描述的抽象机器的规则进行评估。此外,在每一个顺序点,最后存储在对象中的值应与抽象机器规定的值一致,除非经过前面提到的未知因素的修改。116)对具有易失性限定类型的对象的访问是由实现定义的。
实际上,您可以省略tmp,只需写:
*(volatile uint32_t *)INTERRUPT_STATUS_REG_ADDRESS;这将简单地读取位于INTERRUPT_STATUS_REG_ADDRESS的INTERRUPT_STATUS_REG_ADDRESS寄存器;
https://stackoverflow.com/questions/26475335
复制相似问题