2008/05/22 | volatile
类别(每一步) | 评论(0) | 阅读(41) | 发表于 13:28

觉得对自己有点帮助,从某人博客转:

在大多数情况下,把变量缓存在寄存器中是一个非常有价值的优化方法,如果不用的话很可惜。C和C++给你提供了显式禁用这种缓存优化的机会。如果你声明变量是使用了volatile修饰符,编译器就不会把这个变量缓存在寄存器里——每次访问都将去存取变量在内存中的实际位置。

1、中断服务程序中修改的供其它程序检测的变量需要加volatile;

2、多任务环境下各任务间共享的标志应该加volatile;

3、寄存器对应的变量值一般最好加上volatile,例如:

volatile UINT32* Register;    // Register is the address of the register

又如:

 *(volatile UINT32 *) (UINTN) (ApicBase + APIC_REGISTER_ICR_HIGH_OFFSET)  = ICRHigh;
*(volatile UINT32 *) (UINTN) (ApicBase + APIC_REGISTER_ICR_LOW_OFFSET)  = ICRLow;

4、当多条指令往同一个寄存器内按照时序写值时,如果用O2优化,程序只写入最后一条指令的写!显然是错误的!

===============

自己的实践!

用cl test.c /FAcs /Zi /O2编译下面程序。

#include "stdio.h"

unsigned int q;

int main()
{
//  volatile unsigned int *i;
  unsigned int *i;
  unsigned int p;
 
  p = 0x55aa;

  i = (unsigned int *) 0x310;
  *i = p;
  p = *i;   // 如果没有volatile,编译器优化O2认为此步多余,在下一步会直接将0x55aa赋给q;

               // 但是如果i是一个硬件寄存器的地址,需要写入一个值再读出状态值,那么q的值就不是正确的状态值,而是0x55aa!这显然是错误的。
  
  q = p;
 
  return 0;
}

0

评论Comments