我正在学习ARM内联汇编,并且对一个非常简单的功能感到困惑:在arm32和arm64上将x
to的值y
(均为int
类型)赋值,为什么需要使用不同的内容描述?
这是代码:
#include <arm_neon.h>
#include <stdio.h>
void asm_test()
{
int x = 10;
int y = 0;
#ifdef __aarch64__
asm volatile(
"mov %w[in], %w[out]"
: [out] "=r"(y)
: [in] "r"(x)
: "r0" // r0 not working, but r1 or x1 works
);
#else
asm volattile(
"mov %[in], %[out]"
: [out] "=r"(y)
: [in] "r"(x)
: "r0" // r0 works, but r1 not working
);
#endif
printf("y is %d\n", y);
}
int main() {
arm_test();
return 0;
}
在我扎根的android手机上对arm32进行了测试,会r0
生成正确的结果,但r1
不会。对于arm64,r1
还是x1
生成正确的结果,但r0
不会。为什么在arm32和arm64上它们不同?具体的规则是什么?在哪里可以找到?
ARM / AArch64语法为mov dst, src
。
仅当编译器碰巧为"=r"
输出和"r"
输入选择相同的寄存器(或类似的东西,给定额外的x
浮动副本)时,你的asm语句才起作用。
不同的Clobber只会干扰编译器的寄存器分配选择。 查看生成的asm(gcc -S
或在https://godbolt.org/上,尤其是使用-fverbose-asm
。)
通过使约束与模板字符串中的指令不匹配而导致的未定义行为仍然可以起作用。永远不要仅仅因为它与一组编译器选项和周围的代码一起工作就认为asm语句是正确的。
谢谢!我的代码确实使用了错误的语法。修复它会生成正确的结果。