我正在学习汇编代码,并给出了此代码,所以我需要查找此代码的含义。但是我正在尝试使用qtspim进行调试。我知道每个寄存器中的值是什么,但是我仍然不了解这段代码的含义。
如果您找到该模式以及该代码的内容,您能否告诉我该怎么做,以及您在哪种行中知道该模式?谢谢!
public class ListZakazniku {
public static ArrayList<Zakaznik> zakaznici = new ArrayList<>();
public ListZakazniku(){
zakaznici= new ArrayList<Zakaznik>();
}
public void setZakaznici(ArrayList<Zakaznik> zakaznik){
this.zakaznici.clear();
this.zakaznici = zakaznik;
}
public static ArrayList<Zakaznik> getZakaznici() {
return zakaznici;
}
public void add(Zakaznik elbow){
zakaznici.add(elbow);
}
答案 0 :(得分:1)
这是population count, aka popcount, aka Hamming Weight 。 $s0
中的最终结果是输入中1
位的数量。这是一种优化的实现,其结果与将每个位分别移至寄存器的底部并将其加到总计中的效果相同。参见https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetNaive
此实现通过使用SWAR 从2位累加器构建为4位,8位和16位来工作,以进行多个不带的窄加法一条add
指令相互转化。
请注意,它如何屏蔽其他所有位,然后屏蔽每对位,然后屏蔽每组4位。并使用移位使另一对下移以排成add
。像C
(x & mask) + ((x>>1) & mask)
以较大的移位和不同的掩码重复此操作,最终将为您提供所有位的总和(将它们全部都置为位置值1),即输入中的设置位数。
因此,它的GNU C表示为__builtin_popcnt(x)
。
(除了编译器实际上将使用更有效的popcnt:分别为每个字节使用字节查找表,或者以这种方式启动的bithack,但是使用乘以0x01010101
的数字作为水平和4字节到结果的高字节中。因为乘法是移位加法指令。How to count the number of set bits in a 32-bit integer?)
但这是无效的:它需要使用addu
来避免出现错误;如果尝试弹出0x80000000
,则第一个add
将同时具有两个输入= 0x40000000
,从而产生带符号的溢出和故障。
IDK为什么有人在MIPS上使用add
指令。普通的二进制加法指令称为addu
。
在签名上加陷阱加溢出指令是add
,即使您的数字已签名,也很少是您想要的。您可能会忘记它的存在,而使用addu
/ addui