博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(volatile int)(x)与*(volatile int *)(&x)
阅读量:6333 次
发布时间:2019-06-22

本文共 2642 字,大约阅读时间需要 8 分钟。

在stackoverflow上看到这个问题

 

原答主已经回答的很仔细了,不过还不够直观,这里做个试验

1 #include 
2 #include
3 4 //加子函数防止变量优化没了 5 void pfunc(int a, int b) 6 { 7         int i = 0; 8         int sum = 0; 9         for (i = 0; i < b; i++) 10         { 11                 sum += a * i; 12         } 13 14         printf("sum %x\n", sum); 15 } 16 17 int main() 18 { 19         int i = 0x102; 20         int a = (volatile int)i; 21         int b = *(volatile int *)&i; 22 23         pfunc(a, b); 24 }

在arm平台上编译并截取main()的汇编

R0与R1为函数入参,从ldr指令看两者获取i的方式相同

 

1 000083ec 
: 2     83ec:        e92d4800         push        {fp, lr} 3     83f0:        e28db004         add        fp, sp, #4 4     83f4:        e24dd010         sub        sp, sp, #16 5     83f8:        e59f3028         ldr        r3, [pc, #40]        ; 8428
6     83fc:        e50b3010         str        r3, [fp, #-16] 7     8400:        e51b3010         ldr        r3, [fp, #-16] 8     8404:        e50b3008         str        r3, [fp, #-8] 9     8408:        e51b3010         ldr        r3, [fp, #-16] 10     840c:        e50b300c         str        r3, [fp, #-12] 11     8410:        e51b000c         ldr        r0, [fp, #-12] 12     8414:        e51b1008         ldr        r1, [fp, #-8] 13     8418:        eb000003         bl        842c
14     841c:        e1a00003         mov        r0, r3 15     8420:        e24bd004         sub        sp, fp, #4 16     8424:        e8bd8800         pop        {fp, pc} 17     8428:        00000102         andeq        r0, r0, r2, lsl #2

 

加入O1编译

 

 

1 00008430 
: 2     8430:        e52de004         push        {lr}                ; (str lr, [sp, #-4]!) 3     8434:        e24dd00c         sub        sp, sp, #12 4     8438:        e59f0010         ldr        r0, [pc, #16]        ; 8450
5     843c:        e58d0004         str        r0, [sp, #4] 6     8440:        e59d1004         ldr        r1, [sp, #4] 7     8444:        ebffffe8         bl        83ec
8     8448:        e28dd00c         add        sp, sp, #12 9     844c:        e49df004         pop        {pc}                ; (ldr pc, [sp], #4) 10     8450:        00000102         andeq        r0, r0, r2, lsl #2

 

可见此时R0与R1的来源不同,R0(a)的值是将i入栈时候的值,如果此时(在ldr之后)多线程修改该值即入参就出错了(当然在这个例子中不可能,因值是全局初始化的在代码段里,但意思是这个意思),而R1仍从堆栈里取该值保证变量的正确性

结论:

1. 由此可见内核使用*(volatile typeof(x) *)(&x)的方式是必要的并且简化版((volatile typeof(x)(x))并没有起到意想中的效果(因为x是做为取出的值去做强制类型转换,而当它转换时可能已经在寄存器里了)

 

2. 理解这类问题最好方法就是写个demo直接反汇编,一切都清楚了

 

转载于:https://www.cnblogs.com/Five100Miles/p/8460324.html

你可能感兴趣的文章
进行短视频app开发工作时,可以加入它来保护青少年 ...
查看>>
25G DAC无源高速线缆和25G光模块之间的区别
查看>>
乐乐茶完成近2亿元Pre-A轮融资,祥峰投资领投
查看>>
clickhouse修改时区
查看>>
CSS_定位
查看>>
第二十四章:页面导航(六)
查看>>
百度、长沙加码自动驾驶,湖南阿波罗智行科技公司成立 ...
查看>>
Java面试笔试题大汇总一(最全+详细答案)
查看>>
10 个 Linux 中方便的 Bash 别名
查看>>
[Server] 服务器配置SSH登录邮件通知
查看>>
全新 DOCKER PALS 计划上线,带给您不一样的参会体验! ...
查看>>
Android开发之自定义View(二)
查看>>
python爬虫之微打赏(scrapy版)
查看>>
自制操作系统Antz day08——实现内核 (中) 扩展内核
查看>>
poj-1056-IMMEDIATE DECODABILITY(字典)
查看>>
阿里云容器Kubernetes监控(二) - 使用Grafana展现Pod监控数据
查看>>
区块链应用 | 不知道什么时候起,满世界都在谈区块链的事情
查看>>
小程序爆红 专家:对简单APP是巨大打击
查看>>
FarBox--另类有趣的网站服务【转】
查看>>
在非纯色背景上,叠加背景透明的BUTTON和STATIC_TEXT控件
查看>>