汉明重锤(数量中的1个)混合C与组件

ant*_*nt1 2 c x86 assembly bit-manipulation hammingweight

我正在尝试计算数组中有多少个数字 1。

首先我有一个 C lenguaje 代码(工作正常):

int popcount2(int* array, int len){
    int i;
    unsigned x;
    int result=0;
    for (i=0; i<len; i++){
        x = array[i];
        do{
           result+= x & 0x1;
           x>>= 1;
       } while(x);
    }
return result;
}
Run Code Online (Sandbox Code Playgroud)

现在我需要使用 3-6 行代码将 do-while 循环转换为汇编。我写了一些代码,但结果不正确。(我是汇编世界的新手)

int popcount3(int* array, int len){
int  i;
unsigned x;
int result=0;   
for (i=0; i<len; i++){
    x = array[i];
    asm(
    "ini3:               \n"
        "adc $0,%[r]     \n"
        "shr %[x]        \n"
        "jnz ini3        \n"

        : [r]"+r" (result)
        : [x] "r" (x)       );
  }
}
Run Code Online (Sandbox Code Playgroud)

我正在使用 GCC(在 Linux 上)和 Intel 处理器。

Pau*_*l R 5

您从一个非常低效的算法开始 - 如果您使用更好的算法,那么您可能不需要在汇编器上浪费时间。请参阅Hacker's Delight和/或Bit Twiddling Hacks以获取更有效的方法。

另请注意,较新的 x86 CPU 有一条POPCNT指令,该指令在一条指令中完成上述所有操作(您也可以通过内部函数调用它,因此不需要 asm)。

最后,gcc 有一个内置的:__builtin_popcount,它再次满足您所需的一切 - 它将POPCNT在较新的 CPU 上使用,并在较旧的 CPU 上使用等效的 asm。