• 关于Volatile的解读


    一直想看一看 volatile 的用法,之前就看过这种静态量是不会被编译器无意破坏的,但是一直没有搞彻底明白。

    今天查看了大量前辈们的总结,自己又有了新的心得,写下此随笔来分享自己的心得。

    最开始接触 volatile 是在STM32程序的 __IO 中,其中#define __IO  volatile

    (下面一段来自维基百科对Volatile的解读)

    volatile关键字用来阻止(伪)编译器认为的无法“被代码本身”改变的代码(变量/对象)进行优化。如在C语言中,

    volatile关键字可以用来提醒编译器它后面所定义的变量随时有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。

    (上面一段来自维基百科对Volatile的解读)

    在C语言中,编译器会根据你得代码进行优化,而 volatile 最直接的就是,告诉编译器不要优化这一个变量的运算过程。

    (下面图片来自维基百科)

    (上面图片来自维基百科)

    在汇编下,可以很明确的看出使用Volatile后编译器不会让你的代码丢失。

    先说下使用volatile的好处:

    1.volatile允许除了程序以外的事件来改变它的内容,比如硬件直接改变。

    2.每次读取volatile的内容都是直接访问该地址的内容,不是通过cache( 高速缓冲存储器)来访问。

    稍稍解释一下:1.我们告诉编译器,volatile类型的变量的确可能被外部条件改变,比如硬件设备。

    2.正常情况下,如果我们不加volatile的话,在共享地址区的变量程序并不知道它什么时候被改变,你读取的只可能是cache里面的变量,而这个变量可能是过时的变量。

    3.(补充)私有地址里面的内容,程序可以直接访问

    回到我们的截图内容

    #define __IO  volatile

    #define uint32_t  uisigned long

    如果是(volatile unsigned long *) (0x1FFF7A10),再分解看(volatile unsigned long *)是一个为随硬件需要定义的一种地址,前面加上*指针,即直接指向改地址,整个定义#define CPU_Sn0,调用的时候直接向地址寄存器写内容就好了。这是内存机制的方便性,volatile是嵌入式系统开发发一个重要特点。

    再将其展开来分析:(volatile unsigned long *) (0x1FFF7A10)的意思就是将0x1FFF7A10强制转化成volatile unsigned long的指针,然后赋给CPU_Sn0就是表达CPU_Sn0为指向地址的内容了。这里是通过内存寻址访问寄存器,可以进行读/写操作。

    再通过这个volatile去分析,关键字volatile 确保本条指令不会因C 编译器的优化而被省略,且要求每次直接读值。例如用while((unsigned char *)0x1FFF7A10)时,有时系统可能不真正去读0x1FFF7A10的值,而是用第一次读出的值,如果这样,那这个循环可能是个死循环。用了volatile 则要求每次都去读0x1FFF7A10的实际值。那么它就是一个固定的指针,而char *p;是一个指针变量。

    再在前面加一个 “*” :则变成了变量,只不过这是一个地址固定的指针变量。

  • 相关阅读:
    Java的静态块与实例块(转)
    Programming Ability Test学习 1031. Hello World for U (20)
    Programming Ability Test学习 1011. World Cup Betting (20)
    Programming Ability Test学习 1027. Colors in Mars (20)
    Programming Ability Test学习 1064. Complete Binary Search Tree (30)
    Programming Ability Test学习 1008. Elevator (20)
    【maven详解-生命周期】Maven的生命周期和插件
    【maven详解-插件】maven插件学习之源码插件Source Xref
    $(document).ready(){}、$(fucntion(){})、(function(){})(jQuery)onload()的区别
    你还没真的努力过,就轻易输给了懒惰
  • 原文地址:https://www.cnblogs.com/qiaoyonggang/p/11256340.html
Copyright © 2020-2023  润新知