Assembly 计算设置的位数

Assembly 计算设置的位数,assembly,mips,hammingweight,Assembly,Mips,Hammingweight,我想计算二进制数中设置的位数。 例如,用户输入数字97,它是二进制的0110001。程序应该给我3位是用MIPS ISA设置的 我可以在C中实现这一点,但我不知道如何使用汇编代码实现它。您所寻找的通常被称为人口计数(popcount) 上有许多C实现(其中一些非常聪明)。如果您熟悉C语言,那么在分解表达式之后,每种方法都应该有一个合理的翻译成MIPS汇编 如果你的输入域很小(例如0-255),你可以做一个查找表,并使用输入作为偏移量直接获取popcount。因为这听起来像是家庭作业,我不打算给出

我想计算二进制数中设置的位数。 例如,用户输入数字97,它是二进制的0110001。程序应该给我3位是用MIPS ISA设置的


我可以在C中实现这一点,但我不知道如何使用汇编代码实现它。

您所寻找的通常被称为人口计数(popcount)

上有许多C实现(其中一些非常聪明)。如果您熟悉C语言,那么在分解表达式之后,每种方法都应该有一个合理的翻译成MIPS汇编


如果你的输入域很小(例如0-255),你可以做一个查找表,并使用输入作为偏移量直接获取popcount。

因为这听起来像是家庭作业,我不打算给出MIPS代码,但这里是算法(用C编写)。将其转换为MIPS应该很简单:

int bits(unsigned int number)
{
    // clear the accumulator
    int accumulator = 0;
    // loop until our number is reduced to 0
    while (number != 0)
    {
        // add the LSB (rightmost bit) to our accumulator
        accumulator += number & 1;
        // shift the number one bit to the right so that a new
        // bit is in the LSB slot
        number >>= 1;
    }
    return accumulator;
}

Chris给出的链接提供了一些很好的位计数方法。我建议,因为它速度非常快,不需要循环,只需要按位操作,这在汇编中更容易实现

获取程序集代码的另一种方法是使用C编写代码,对其进行编译,然后查看输出程序集(大多数编译器都可以生成程序集文件输出(-S for gcc,但确保通过-O0禁用优化以更容易理解代码),或者允许您查看已反汇编的二进制文件)。它应该为你指明正确的方向

作为一个轶事,我曾经在PowerPC上做过一些测试(我知道不是MIPS…),寻找32位整数中最快的位计数方法。我链接的方法是迄今为止最好的方法,直到我做了一个字节大小的查找表并对其进行了4次寻址。ALU似乎比引用缓存慢(通过算法运行大约一百万个数字)