当在GCC的内联asm中使用数组元素作为输出内存约束时,为什么需要指定“memory”clobber?

时间:2012-09-13 09:04:20

标签: arrays gcc constraints mips inline-assembly

我正在尝试对音频编解码器进行一些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?

1 个答案:

答案 0 :(得分:1)

使用和不使用"memory"约束(使用gcc -S ...)查看生成的整个函数的汇编代码。看起来gcc在s[i]语句之前从内存加载的寄存器中有asm()的副本,并且它没有意识到该寄存器包含{{1}之后的过时信息除非您添加asm()约束。