来看一段代码:

 
  
  1. volatile unsigned  long *gpmcon = (volatile unsigned long*)0x7F008820;  
  2.  
  3. *gpmcon = 0x1111;  

有些时候会有些糊涂,看不太懂。

那么我们来这样的理解:

来看

 
  
  1. int a;  
  2. a = 1; 

 这个很简单 定义一个a  让a 等于1

好,继续来看

 
  
  1. int a;  
  2. int *p;  
  3.  
  4. p = &a;  
  5. *p = 1; 

这里我们定义了一个指针,把a的地址赋值给了p,然后再对p进行赋值,这里的效果是一样的,都对a赋值了1

好,化简一下

 
  
  1. int a;  
  2. int *p = &a;  //这里记住 p = 某个地址  
  3. *p = 1; 

这里要知道的是,*p 是赋值的是某个地址

比如现在我们的地址是:0x7F008820

好,那么我们现在可以这样写:

 
  
  1. int *p = 0x7F008820;  
  2. *p = 0x1111; 

如果为了防止编译器警告类型不一致,那么我们再添加一下类型转换:

 
  
  1. int *p = (int *)0x7F008820;    
  2. *p = 0x1111;  

好的,到这里,我们就理解了,回到的原来的,把int修改成unsigned long

 那么我们就得到了

 
  
  1.  unsigned  long *gpmcon = (unsigned long*)0x7F008820;  
  2.  
  3. *gpmcon = 0x1111;  

 

现在就得到我们要的表达式了,这里还少了一个volatile 

这个是防止编译器优化

来看下面的程序你就明白了:

 
  
  1. //比如说  
  2. main()  
  3. {  
  4.    int a;  
  5.     a = 1;  
  6.     printf("hello world");  

因为呢,程序中只是打印了hello world 而变量a 并没有用到,所以编译器有时候把它优化了,程序就变成了下面这个样子:

 

现在就知道为什么在操作寄存器的时候,为什么加上volatile 了吧,

因为程序有时候认为操作寄存器对程序没有影响,但是我们却需要去设置,这个时候我们就加上这个volatile 防止优化。

 

 

 

 

 
  
  1. //比如说  
  2. main()  
  3. {   
  4.     printf("hello world");