★★★ 个人博客导读首页—点击此处 ★★★

环境aarch64的交叉编译器
我们将C语言翻译成汇编代码,来看volatile关键字的作用

我们先看一段C语言代码

void udelay(uint64_t usec)
{uint64_t start, cnt, delta,freq;volatile uint64_t delta_us = 0;  //------------------在这里定义了一个volatile变量uint64_t reference_ratio = 16;if(timer_start == 0){generic_timer_start();start = read_cntpct_el0();delta_us = 1000;  //------------------ 给这个变量赋值100while(delta_us) //------------------ 使用这个变量,这里是判断该变量是否等于0,然后走相应逻辑{cnt = read_cntpct_el0();if(cnt != start)break;delta_us--;if(delta_us == 0){base_frequency = 0;}}INFO("base_frequency %ld\n",base_frequency);}
......
}

翻译成汇编后,从汇编代码来看,delta_us=1000,直接将1000写道栈尾中了.
while(delta_us)代码,需要读出delta_us,也是种栈尾种读出来的

00000000002034b4 <udelay>:2034b4:       a9bd7bfd        stp     x29, x30, [sp,#-48]!2034b8:       910003fd        mov     x29, sp2034bc:       a90153f3        stp     x19, x20, [sp,#16]2034c0:       aa0003f3        mov     x19, x02034c4:       b00000c0        adrp    x0, 21c000 <xxx_middle_mem_pool+0xa40>2034c8:       f90017bf        str     xzr, [x29,#40]2034cc:       900000d4        adrp    x20, 21b000 <buf+0xdb8>2034d0:       b94f9c00        ldr     w0, [x0,#3996]2034d4:       340000a0        cbz     w0, 2034e8 <udelay+0x34>2034d8:       f9412a80        ldr     x0, [x20,#592]2034dc:       b50003a0        cbnz    x0, 203550 <udelay+0x9c>2034e0:       d37cee73        lsl     x19, x19, #42034e4:       14000014        b       203534 <udelay+0x80>2034e8:       97ffffdd        bl      20345c <generic_timer_start>2034ec:       d53be022        mrs     x2, cntpct_el02034f0:       d2807d00        mov     x0, #0x3e8  //------------------------ 0x3e8-#1000给x0赋值1000,x0就表示delta_us变量2034f4:       f90017a0        str     x0, [x29,#40] //------------------------ 将这个变量写到栈尾内存(其实可能是main-memory,也可能写入到了cache中)2034f8:       f9412a80        ldr     x0, [x20,#592]2034fc:       f94017a1        ldr     x1, [x29,#40] //------------------------ 将这个变量从栈尾内存读出来,放到X1中203500:       b4000161        cbz     x1, 20352c <udelay+0x78> //------------------------ 比较x1是否等于0,然后走相应的分支203504:       d53be021        mrs     x1, cntpct_el0203508:       eb02003f        cmp     x1, x220350c:       54000101        b.ne    20352c <udelay+0x78>203510:       f94017a1        ldr     x1, [x29,#40]  //----------------------- 在操作(delta_us--)时,再次从内存中去读203514:       d1000421        sub     x1, x1, #0x1   // 这样对应 delta_us--203518:       f90017a1        str     x1, [x29,#40]20351c:       f94017a1        ldr     x1, [x29,#40]203520:       eb1f003f        cmp     x1, xzr203524:       9a9f1000        csel    x0, x0, xzr, ne

我们去除volatile关键字后,再翻译成汇编:
uint64_t delta_us = 0; //------------------在这里定义了一个volatile变量
翻译成汇编后,从汇编代码来看,delta_us=1000,只是将1000写入到了x0寄存器中

0000000002034b4 <udelay>:2034b4:       a9be7bfd        stp     x29, x30, [sp,#-32]!2034b8:       910003fd        mov     x29, sp2034bc:       f9000bf3        str     x19, [sp,#16]2034c0:       aa0003f3        mov     x19, x02034c4:       b00000c0        adrp    x0, 21c000 <xxx_middle_mem_pool+0xa40>2034c8:       b94f9c00        ldr     w0, [x0,#3996]2034cc:       35000160        cbnz    w0, 2034f8 <udelay+0x44>2034d0:       97ffffe3        bl      20345c <generic_timer_start>2034d4:       d53be021        mrs     x1, cntpct_el02034d8:       d2807d00        mov     x0, #0x3e8  //------------------------ 0x3e8-#1000给x0赋值100,x0就表示delta_us变量2034dc:       d53be022        mrs     x2, cntpct_el02034e0:       eb01005f        cmp     x2, x12034e4:       540000a1        b.ne    2034f8 <udelay+0x44>2034e8:       f1000400        subs    x0, x0, #0x1   //------------------ 这行对应的delta_us--2034ec:       54ffff81        b.ne    2034dc <udelay+0x28>2034f0:       900000c0        adrp    x0, 21b000 <buf+0xdb8>2034f4:       f901281f        str     xzr, [x0,#592]2034f8:       900000c0        adrp    x0, 21b000 <buf+0xdb8>2034fc:       f9412801        ldr     x1, [x0,#592]

总结volatile关键字的作用:其实就算告诉编译器,我要读写的数据,不要从X0-X30通用寄存器中读取,每次都要从内存中去读取,这里说的内存可能是主内存(main-memory)、也可能是各级cache等

[实验]-从汇编代码来看volatile关键字的作用相关推荐

  1. 一文搞懂Volatile关键字的作用

    前言 Volatile关键字的作用主要有如下两个: 1.线程的可见性:当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值. 2. 顺序一致性:禁止指令重排序. 一.线程可见性 我们先通过一个 ...

  2. volatile关键字的作用、原理

    在只有双重检查锁,没有volatile的懒加载单例模式中,由于指令重排序的问题,我确实不会拿到两个不同的单例了,但我会拿到"半个"单例. 而发挥神奇作用的volatile,可以当之 ...

  3. java volatile关键字的作用_java volatile关键字作用及使用场景详解

    1. volatile关键字的作用:保证了变量的可见性(visibility).被volatile关键字修饰的变量,如果值发生了变更,其他线程立马可见,避免出现脏读的现象.如以下代码片段,isShut ...

  4. 【说一千道一万】volatile关键字的作用和synchronized的关系

    [说一千道一万]volatile关键字的作用和synchronized的关系 volatile这个关键字在面试的时候通常会拿出来跟synchronized作比较,这也是比较基础的面试题目,这里自己总结 ...

  5. 深入理解并发内存模型||JMM与内存屏障||多核并发缓存架构 ||JMM内存模型||volatile 关键字的作用 ||JMM 数据原子操作||JMM缓存不一致的问题

    深入理解并发内存模型||JMM与内存屏障 多核并发缓存架构 JMM内存模型 volatile 关键字的作用 JMM 数据原子操作 JMM缓存不一致的问题

  6. 24.volatile关键字的作用、volatile原理、可见性、内存屏障、volatile性能、transient

    24.volatile关键字的作用 24.1.volatile原理 24.2.可见性 24.3.内存屏障 24.4.volatile性能 25.transient 24.volatile关键字的作用 ...

  7. volatile关键字的作用

    总结:volatile关键字是用于保证有序性和可见性.当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值. 可见性: 指当多个线程 ...

  8. c语言中volatile关键字的作用

    读文章之前 可以先看一下<程序员的自我修养 >第28页 过度优化. volatile 提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直 ...

  9. c#中volatile关键字的作用

    恐怕比较一下volatile和synchronized的不同是最容易解释清楚的.volatile是变量修饰符,而synchronized则作用于一段代码或方法:看如下三句get代码: int i1;  ...

最新文章

  1. java线程池的使用学习
  2. 【企业管理】整理和思考-陈春花:2022年经营关键词
  3. SpaceX完成“星舰”空中悬停,距载人探火星还远吗?
  4. 头像星球html,HTML5 Canvas 星球大战黑武士头像
  5. Spring缓存注解@Cache使用
  6. jQuery源码分析 Sizzle选择器
  7. 简单的读取文件和写入文件
  8. JS开发工具WebStorm使用快捷键
  9. 31省“5G应用”主攻方向+责任单位一览!
  10. tomcat常见漏洞
  11. MATLAB雷达信号处理
  12. ECharts数据可视化(入门)
  13. spring boot启动报错:Reason: Canonical names should be kebab-case (‘-‘ separated), lowercase
  14. c#加粗代码_C# 字体加粗按钮
  15. 怎么自己建网站?自己建网站要注意以下4点
  16. Halcon2019软件安装教程
  17. 自动将BAT文件转换为EXE
  18. 市政管网检测机器人收费标准_滦州市机器人检测随叫随到收费标准
  19. 缓存模式【缓存使用几种模式】【刘新宇】
  20. python set集合 交集,并集,差集,对称差集

热门文章

  1. 2021年改造数据中心未来最需要的技能
  2. mysql 从裤3523_MySQL出现3523错误分析
  3. AI之NLP:自然语言处理技术简介(是什么/学什么/怎么用)、常用算法、经典案例之详细攻略(建议收藏)
  4. Python之sklearn:GridSearchCV()和fit()函数的简介、具体案例、使用方法之详细攻略
  5. Java:计算机编程语言Java的简介、编程环境/工具、如何学习Java之详细攻略
  6. 成功解决AttributeError: module 'cv2.cv2' has no attribute 'CV_CAP_PROP_FPS'和 'CV_CAP_PROP_FRAME_WIDTH'
  7. 第五章Bookstrap
  8. jmeter脚本结合ant执行测试用例并生成测试报告
  9. HDU 3501 Calculation 2
  10. GPS 气压计高度测量