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 处理器。
您从一个非常低效的算法开始 - 如果您使用更好的算法,那么您可能不需要在汇编器上浪费时间。请参阅Hacker's Delight和/或Bit Twiddling Hacks以获取更有效的方法。
另请注意,较新的 x86 CPU 有一条POPCNT指令,该指令在一条指令中完成上述所有操作(您也可以通过内部函数调用它,因此不需要 asm)。
最后,gcc 有一个内置的:__builtin_popcount,它再次满足您所需的一切 - 它将POPCNT在较新的 CPU 上使用,并在较旧的 CPU 上使用等效的 asm。