在GCC内联汇编中,有两种方法可以防止优化:__volatile__
关键字并将"memory"
插入到clobber寄存器列表中。
我的问题是与__volatile__
和"memory"
有什么不同 - 似乎它们是相同的...但是,今天我遇到了奇怪的情况,这表明他们已经绝对不同! (当我使用"memory"
时,我的程序在端口I / O函数中有一个错误,但是当我使用__volatile__
时,它变好了。)
有什么区别?
答案 0 :(得分:2)
我对GCC文档的解读是__volatile__
关键字用于具有副作用的程序集:也就是说,它除了从输出产生输入之外还执行其他操作。在您的情况下,我想“端口I / O功能”会导致副作用。
"memory"
clobber仅用于读取/写入输入/输出操作数以外的内存的程序集。虽然这是副作用,但并非所有副作用都涉及记忆。
来自manual:
Extended asm语句的典型用法是操作输入值以生成输出值。但是,您的asm语句也可能产生副作用。如果是这样,您可能需要使用volatile限定符来禁用某些优化。
和
“memory”clobber告诉编译器汇编代码对输入和输出操作数中列出的项以外的项执行内存读取或写入(例如访问其中一个输入参数指向的内存)。
答案 1 :(得分:0)
使用__volatile__
,您保证始终从RAM 中检索值,从而通过CPU缓存。正如Michael Rawson的回答中所述,这会产生副作用,但在某种意义上说,通过CPU缓存进行的正常优化是“禁用”而不是其他任何内容。
在您的情况下,从I / O端口(并存储在变量中)的值可以比CPU缓存失效更快地更新,因此您可以读取“旧”值。使用__volatile__
,您只需读取非缓存值。
您还可以看到:this post(我不知道您的架构是否为ARM,但te概念是相同的。)