GCC内联汇编中的一个简单while循环

Ren*_* R. 5 c++ gcc gnu-assembler inline-assembly

我想使用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;
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

正如评论中提到的那样,该汇编器代码确实是一个do {...} while循环,但实际上确实做了相同的工作。

那段代码的真正奇怪之处在于,一开始它对我来说效果很好。但是当我后来试图使其在另一个项目中工作时,似乎似乎什么也做不了。我什至制作了工作项目的1:1副本,再次进行编译,...结果仍然是随机的。

也许我对输入​​操作数使用了错误的约束,但是到目前为止,实际上我已经尝试了几乎所有输入操作数,而且我还没有真正的想法。特别令我困惑的是,它在某些情况下仍然有效。

尽管我在上大学时就已经学过,但我并不是ASM的专家。请注意,我不是在寻求优化-我只是想了解内联汇编的工作方式。所以这是我的问题:我的尝试有根本性的错误吗?还是我在这里犯了一个更细微的错误?提前致谢。

(使用g ++ MinGW Win32 x86 v.4.8.1)

更新资料

到目前为止,我已经尝试了所有在此提出的建议。我特别尝试过

  • 使用“ q”操作数约束而不是“ r”,有时会起作用,有时却不起作用,
  • ... : [aptr] "=r" (arr) : "0" (arr) ...相反,写相同的结果,
  • 甚至... : [aptr] "+r" (arr) : ...,还是一样。

同时,我非常了解官方文档,但仍然看不到我的错误。

Tim*_*win 2

aptr您正在修改不允许的输入操作数 ( )。要么限制它与输出操作数匹配,要么将其更改为输入/输出操作数。