我正在尝试对音频编解码器进行一些asm级别(带有一些DSP扩展的MIPS)优化。有一些DSP处理涉及到之后,我要点结果需要存储回一个数组。这是我认为应该这样做的代码:
asm(
eDSP_MFLO(8, 1) // move the accumulated result to $8
"sw $8, %0\n" // result => array
: "=m"(s[i])
:: "$8"
);
问题是这个代码是否有效(我没有在数组中得到垃圾),这取决于它的周围代码,除非我将“内存”添加到clobber列表中:
asm(
eDSP_MFLO(8, 1) // move the accumulated result to $8
"sw $8, %0\n" // result => array element s[i]
: "=m"(s[i])
:: "$8", "memory"
);
我很难理解为什么有必要。我不会质疑它是否我自己计算了asm块中的数组的偏移量,以便编译器不知道哪些内存地址已被更改,但是由于GCC自己执行这些步骤,为什么它需要额外的“内存” “clobber?
答案 0 :(得分:1)
使用和不使用"memory"
约束(使用gcc -S ...
)查看生成的整个函数的汇编代码。看起来gcc在s[i]
语句之前从内存加载的寄存器中有asm()
的副本,并且它没有意识到该寄存器包含{{1}之后的过时信息除非您添加asm()
约束。