参考:http://stackoverflow.com/questions/14950614/working-of-asm-volatile-memory

asmvolatile("":::"memory");

creates a compiler level memory barrier forcing optimizer to not re-order memory accesses across the barrier.

For example, if you need to access some address in a specific order (probably because that memory area is actually backed by a different device rather than a memory) you need to be able tell this to the compiler otherwise it may just optimize your steps for the sake of efficiency.

Assume in this scenario you must increment a value in address, read something and increment another value in an adjacent address.

int c(int *d, int *e) {int r;d[0] += 1;r = e[0];d[1] += 1;return r;
}

Problem is compiler (gcc in this case) can rearrange your memory access to get better performance if you ask for it (-O). Probably leading to a sequence of instructions like below:

00000000 <c>:0:   4603        mov r3, r02:   c805        ldmia   r0, {r0, r2}4:   3001        adds    r0, #16:   3201        adds    r2, #18:   6018        str r0, [r3, #0]a:   6808        ldr r0, [r1, #0]c:   605a        str r2, [r3, #4]e:   4770        bx  lr

Above values for d[0] and d[1] are loaded at the same time. Lets assume this is something you want to avoid then you need to tell compiler not to reorder memory accesses and that is to use asm volatile("" ::: "memory").

int c(int *d, int *e) {int r;d[0] += 1;r = e[0];asm volatile("" ::: "memory");d[1] += 1;return r;
}

So you'll get your instruction sequence as you want it to be:

00000000 <c>:0:   6802        ldr r2, [r0, #0]2:   4603        mov r3, r04:   3201        adds    r2, #16:   6002        str r2, [r0, #0]8:   6808        ldr r0, [r1, #0]a:   685a        ldr r2, [r3, #4]c:   3201        adds    r2, #1e:   605a        str r2, [r3, #4]10:   4770        bx  lr12:   bf00        nop

It should be noted that this is only compile time memory barrier to avoid compiler to reorder memory accesses, as it puts no extra hardware level instructions to flush memories or wait for load or stores to be completed. CPUs can still reorder memory accesses if they have the architectural capabilities.

This sequence is a compiler memory access scheduling barrier, as noted in the article referenced by Udo. This one is GCC specific - other compilers have other ways of describing them, some of them with more explicit (and less esoteric) statements.

__asm__ is a gcc extension of permitting assembly language statements to be entered nested within your C code - used here for its property of being able to specify side effects that prevent the compiler from performing certain types of optimisations (which in this case might end up generating incorrect code).

__volatile__ is required to ensure that the asm statement itself is not reordered with any other volatile accesses any (a guarantee in the C language).

memory is an instruction to GCC that (sort of) says that the inline asm sequence has side effects on global memory, and hence not just effects on local variables need to be taken into account.

__asm__ __volatile__(: : :memory);相关推荐

  1. #define barrier() __asm__ __volatile__(: : :memory) 中的memory是gcc的东西

    gcc内嵌汇编简介 在内嵌汇编中,可以将C语言表达式指定为汇编指令的操作数,而且不用去管如何将C语言表达式的值读入哪个寄存器,以及如何将计算结果写回C 变量,你只要告诉程序中C语言表达式与汇编指令操作 ...

  2. __asm__ __volatile__(: : :memory)

    memory 强制gcc编译器假设RAM所有内存单元均被汇编指令修改,这样cpu中的registers和cache中已缓存的内存单元中的数据将作废.cpu将不得不在需要的时候重新读取内存中的数据.这就 ...

  3. __asm__ __volatile__ GCC的内嵌汇编语法 ATT汇编语言语法(Z)

    此文在网上到处转载,已不知原出处,我也将之记录在此,并改正其中的一些小笔误. 开 发一个OS,尽管绝大部分代码只需要用C/C++等高级语言就可以了,但至少和硬件相关部分的代码需要使用汇编语言,另外,由 ...

  4. __asm__ __volatile__内嵌汇编用法简述

    __asm__ __volatile__内嵌汇编用法简述 在阅读C/C++原码时经常会遇到内联汇编的情况,下面简要介绍下__asm__ __volatile__内嵌汇编用法.因为我们华清远见教学平台是 ...

  5. __asm__ __volatile__ 嵌入式内嵌汇编语法解构

    __asm__ __volatile__ 嵌入式内嵌汇编语法解构 带有C/C++表达式的内联汇编格式为: __asm__ __volatile__("Instruction List&quo ...

  6. AVR全局全能中断 #define sei() __asm__ __volatile__ (sei ::) 是什么意思

    GCC 嵌入汇编的写法 1,标准C语言没有实现开关中断,所以需要内联汇编来实现. __asm__ __volatile__ ("sei" ::) __asm__ 是关键字,标明后面 ...

  7. 理解 Memory barrier(内存屏障)无锁环形队列

    Memory barrier 简介 程序在运行时内存实际的访问顺序和程序代码编写的访问顺序不一定一致,这就是内存乱序访问.内存乱序访问行为出现的理由是为了提升程序运行时的性能.内存乱序访问主要发生在两 ...

  8. 理解 Memory barrier(内存屏障)【转】

    转自:http://name5566.com/4535.html 参考文献列表: http://en.wikipedia.org/wiki/Memory_barrier http://en.wikip ...

  9. 一文讲解,Linux内核——Memory Barrier(内存屏障)

    本文例子均在 Linux(g++)下验证通过,CPU 为 X86-64 处理器架构.所有罗列的 Linux 内核代码也均在(或只在)X86-64 下有效. 本文首先通过范例(以及内核代码)来解释 Me ...

最新文章

  1. oss图片数据转图片二进制数据_图片数据不够快来试试这些数据增强
  2. python写mapreduce_用python写MapReduce函数——以WordCount为例
  3. ios下使用rsa算法与php进行加解密通讯
  4. 安装flash-----纠结
  5. nginx 配置后网站图片加载出来一半或者不出来
  6. 数据结构之链式队列的优化
  7. 外媒:三星电子正与华为商讨芯片代工事宜
  8. DIV高度自适应方法汇总-----摘自网友
  9. iOS开发:为什么你的学习效率如此低,为什么你很迷茫?
  10. 面试官:new Object[5] 一共创建了几个对象?
  11. excel文件设置的工作表保护如何撤销
  12. MFC控件重叠显示问题
  13. 史上最全python常用英语单词,建议收藏
  14. 中国最美的100首情诗
  15. HBASE学习使用经验
  16. 使用python+opencv写一个简单的条形码识别代码
  17. 织梦DEDE正则查找批量替换数据库自定义内容
  18. opencv自己生成标定板
  19. iOS开发:图标生成器Prepo 的使用,讲的明明白白
  20. 玩转OSGI-ApacheFelix(一)框架启动部署

热门文章

  1. 洛谷4400 BlueMary的旅行(分层图+最大流)
  2. vue 本地环境API代理设置和解决跨域
  3. 28. LAST() 函数
  4. Javascript闭包概念剖析
  5. DoraCMS 源码知识点备注
  6. 数学:《线性代数》矩阵运算
  7. [小故事大道理] -- 蜜蜂为何不如苍蝇
  8. Vue v-for使用详解
  9. oracle 12c dg新特性,Oracle 12c DG新特性---一键switchover
  10. 2 shell 锂基脂_壬二酸和癸二酸制备的复合锂基脂到底有那些差别!