值大小与约束和修饰符指定的寄存器大小不匹配

value size does not match register size specified by the constraint and modifier

在arm64中,编译下面的内联汇编会出现如下警告:

value size does not match register size specified by the constraint and modifier [-Wasm-operand-widths].

这是因为arm64的寄存器是64位的

int a = 1;
int b = 2;
asm volatile(
   "add %[a], %[a], %[b]  \n"
   :
   [a] "+r"(a)
   :
   [b] "r"(b)
   :
    );

And clang give the fix advice, use constraint modifier "w".

这个警告的关键是不匹配的。在 arm64 中,寄存器是 64 位宽度,但是 int/float 变量是 32 位。如果类型是 double/int64_t 或变量是指针,则不会引起警告。所以,你可以试试这个方法。

正如@David Wohlferd 在推荐中提到的那样,只需使用 %w[a] 替换 %[a]

即在ARM64平台上,你还想使用32位寄存器,那么在%和代表寄存器的对应数字之间插入一个w

于是整个程序修改为:

#include <stdio.h>
#include <arm_neon.h>

int main() {

    int a = 1;
    int b = 2;
    asm volatile(
        "add %w[a], %w[a], %w[b]  \n"
        :
        [a] "+r"(a)
        :
        [b] "r"(b)
        :
    );
    printf("after process, a=%d\n", a);

    return 0;
}

顺便说一句,如果你对 arm 内联汇编程序一无所知并且像这个问题的作者一样有类似的困惑,这个 CSDN blog (in Chinese) 值得一读。

value size does not match register size specified by the constraint and modifier

表示:

你的变量 32bit 不匹配 与 ARM64 的 64bit 寄存器

你可以:

  • 将您的变量更改为 64bit
long a = 1;
long b = 2;
asm volatile(
   "add %[a], %[a], %[b]  \n"
   : [a] "+r"(a)
   : [b] "r"(b)
   :);

  • 使用32bit=Word寄存器,通过添加前缀w
    • clang 建议
int a = 1;
int b = 2;
asm volatile(
   "add %w[a], %w[a], %w[b]  \n"
   : [a] "+r"(a)
   : [b] "r"(b)
   :);