Assembly MIPS程序集中2个二进制数之间的位差

Assembly MIPS程序集中2个二进制数之间的位差,assembly,mips,smips,Assembly,Mips,Smips,因此,我必须创建一个MIPS汇编程序,从2个寄存器中读取2个数字($s0和$s1),并计算这2个数字的差异位数。并将结果存储在$s2寄存器中。 我还必须用尽可能少的命令来完成上述所有任务。 我在纸上尝试了一些XOR操作,但我不太明白如何计算不同位的数量 如果有人能帮忙,欢迎你来。 提前感谢将位异或在一起,然后计算结果数字中的位数。为此,您可以循环每个位,检查它是否已设置(通过使用位掩码和位移位),然后递增计数器 我故意把这个含糊不清的地方留下来,因为这是让你们自己弄清楚的。这里有一种方法可以避免

因此,我必须创建一个MIPS汇编程序,从2个寄存器中读取2个数字($s0和$s1),并计算这2个数字的差异位数。并将结果存储在$s2寄存器中。 我还必须用尽可能少的命令来完成上述所有任务。 我在纸上尝试了一些XOR操作,但我不太明白如何计算不同位的数量

如果有人能帮忙,欢迎你来。
提前感谢

将位异或在一起,然后计算结果数字中的位数。为此,您可以循环每个位,检查它是否已设置(通过使用位掩码和位移位),然后递增计数器


我故意把这个含糊不清的地方留下来,因为这是让你们自己弄清楚的。

这里有一种方法可以避免在32位上循环。它重复清除所有位,但最左边的位除外,同时计算它们的数量

  // x and y are the bits to compare
  int z=x^y;  // only bits different between x and y are set
  int w;
  int cnt=0;
  while(w=z&-z) { //w only has the left bit in z set
    cnt++;
    z^=w; // clear the processed bit
  }
它基于一个众所周知的特性,
x&-x
等于
x
中的较低权重设置位


内部循环需要5条mips指令。

使用无循环pop计数代码的C示例:

    int x, y, z;
    // ...
    z = x^y;   // x and y are inputs
    z -= (z >> 1) & 0x55555555;                      // 16   2 bit counts
    z = (z & 0x33333333) + ((z >> 2) & 0x33333333);  //  8   4 bit counts
    z = (z + (z >> 4)) & 0x0f0f0f0f;                 //  4   8 bit counts
    z = (z * 0x01010101) >> 24;                      //  1  32 bit count

尽可能多地移位寄存器宽度,并将带进位的零添加到另一个寄存器,使用
z&=z-1
习惯用法清除最低设置位,而不是实际隔离它,然后使用XOR清除它。只有2条指令加上计数器增量和
bne
。从5个减少到4个。