我想使用 GCC 扩展的内联 ASM 编写以下循环:
long* arr = new long[ARR_LEN]();
long* act_ptr = arr;
long* end_ptr = arr + ARR_LEN;
while (act_ptr < end_ptr)
{
*act_ptr = SOME_VALUE;
act_ptr += STEP_SIZE;
}
delete[] arr;
long
分配一个具有长度的类型数组ARR_LEN
并进行零初始化。循环以 为增量遍历数组STEP_SIZE
。每个触摸的元素都设置为SOME_VALUE
。
好吧,这是我在 GAS 中的第一次尝试:
long* arr = new long[ARR_LEN]();
asm volatile
(
"loop:"
"movl %[sval], (%[aptr]);"
"leal (%[aptr], %[incr], 4), %[aptr];"
"cmpl %[eptr], %[aptr];"
"jl loop;"
: // no output
: [aptr] "r" (arr),
[eptr] "r" (arr + ARR_LEN),
[incr] "r" (STEP_SIZE),
[sval] "i" (SOME_VALUE)
: "cc", "memory"
);
delete[] arr;
正如评论中提到的,这个汇编代码确实更像是一个do {...} while
循环,但实际上它确实做了同样的工作。
这段代码的奇怪之处在于,它起初对我来说很好用。但是当我后来试图让它在另一个项目中工作时,它似乎什么也做不了。我什至制作了一些工作项目的 1:1 副本,再次编译......结果仍然是随机的。
也许我对输入操作数采取了错误的约束,但我实际上已经尝试了几乎所有的约束,而且我没有真正的想法。特别让我感到困惑的是,它在某些情况下仍然有效。
我不是 ASM 方面的专家,尽管我在大学时就学会了它。请注意,我不是在寻找优化——我只是想了解内联汇编是如何工作的。所以这是我的问题:我的尝试有什么根本上的错误,还是我在这里犯了一个更微妙的错误?提前致谢。
(使用 g++ MinGW Win32 x86 v.4.8.1)
更新
到目前为止,我已经尝试了这里提供的每一个建议。特别是我试过
- 使用“q”操作数约束而不是“r”,有时有效,有时无效,
... : [aptr] "=r" (arr) : "0" (arr) ...
而是写,同样的结果,- 甚至
... : [aptr] "+r" (arr) : ...
,还是一样。
同时,我对官方文档非常了解,但我仍然看不到我的错误。