[Rn]!
进行STR操作时自动递增寄存器的基地址?我已经阅读了文档,但没有找到明确的答案,主要是因为该命令语法适用于LDR和STR两种情况。理论上来说,它们都能使用递增操作,但我没有找到任何关于存储(LDR操作正常)的自动递增示例。我编写了一个小程序,在向量中存储了两个数字。当执行完毕后,out
的内容应该是 {1, 2}
,但实际情况是存储覆盖了第一个字节,似乎自动递增没有起作用。#include <stdio.h>
int main()
{
int out[]={0, 0};
asm volatile (
"mov r0, #1 \n\t"
"str r0, [%0]! \n\t"
"add r0, r0, #1 \n\t"
"str r0, [%0] \n\t"
:: "r"(out)
: "r0" );
printf("%d %d\n", out[0], out[1]);
return 0;
}
编辑: 虽然答案对于常规的加载和存储是正确的,但我发现优化器会混乱向量指令(如vldm/vstm)上的自动增量。例如,以下程序:
#include <stdio.h>
int main()
{
volatile int *in = new int[16];
volatile int *out = new int[16];
for (int i=0;i<16;i++) in[i] = i;
asm volatile (
"vldm %0!, {d0-d3} \n\t"
"vldm %0, {d4-d7} \n\t"
"vstm %1!, {d0-d3} \n\t"
"vstm %1, {d4-d7} \n\t"
:: "r"(in), "r"(out)
: "memory" );
for (int i=0;i<16;i++) printf("%d\n", out[i]);
return 0;
}
编译器使用
g++ -O2 -march=armv7-a -mfpu=neon main.cpp -o main
在最后8个变量的输出中会产生无意义的字符,因为优化器保留了递增的变量并将其用于printf。换句话说,out[i]
实际上是out[i+8]
,所以打印出来的前8个值是向量的最后8个值,其余的是超出边界的内存位置。
我尝试过在代码中使用不同组合的volatile
关键字,但只有在使用-O0
标志编译或者使用一个易失性向量而不是指针和new时行为才会改变,例如:
volatile int out[16];