c语言 - MIPS汇编代码 - 试图找出这个代码是关于什么的



我正在学习汇编代码,并且给定此代码,我需要找到此代码的内容。但是,我正在尝试使用QTSPIM进行调试。我知道每个寄存器内的值是多少,但我仍然不明白此代码是什么。

如果您找到了模式以及该代码的内容,您能告诉我如何做到这一点,以及在哪一行中知道该模式?谢谢!

.text
.globl main

.text
main:
li $s0, 0x00BEEF00 ##given $s0= 0x00BEEF00
Init:
li $t0, 0x55555555
li $t1,0x33333333
li $t2,0x0f0f0f0f
li $t3,0x00ff00ff
li $t4,0x0000ffff
Step1: and $s1, $s0, $t0
srl $s0,$s0,1
and $s2,$s0,$t0
add $s0,$s1,$s2
Step2: and $s1,$s0,$t1
srl $s0,$s0,2
and $s2,$s0,$t1
add $s0,$s1,$s2

Step3: and $s1,$s0,$t2
srl $s0,$s0,4
and $s2,$s0,$t2
add $s0,$s1,$s2
Step4: and $s1,$s0,$t3
srl $s0,$s0,8
and $s2,$s0,$t3
add $s0,$s1,$s2
Step5: 
and $s1,$s0,$t4
srl $s0,$s0,16
and $s2,$s0,$t4
add $s0,$s1,$s2
End:
andi $s0,$s0,0x003f

在此处输入图像描述

在此处输入图像描述

MIPS解释

这是一个人口计数,又称爆炸式,又称锤子的重量$s0中的最终结果是输入中的1位数。这是一个优化的实现,其结果与将每个位分开移到寄存器的底部并将其添加到总计相同。参见https://graphics.stanford.edu/~seander/bithacks.html#countbitssetnenaive

使用swar ,该实现从2位累加器到4位,8位和16位的构建作用,使用swar 进行多个狭窄的添加,这些狭窄添加不会彼此携带一项add指令。

请注意,它如何掩盖每隔一点,然后是每一位,然后是每组4位。并使用轮班将另一对降低到add排队。像C
(x & mask) + ((x>>1) & mask)

重复较大的偏移,另一个掩码最终为您提供所有位的总和(将它们都视为具有1个位置为1的位置(,即输入中的设置位数。

所以GNU C表示为__builtin_popcnt(x)

(除了编译器实际上将使用一个更有效的popcnt:单独使用每个字节的字节查找表,或者是以这种方式启动的bithack,但使用乘以 0x01010101之类的数字来水平总和4个字节4结果的字节。因为乘法是一个移位指令。如何计算32位整数中的设置位数?(


,但这被打破了:它需要使用addu来避免故障;如果您尝试popcnt 0x80000000,则第一个add将具有两个输入= 0x40000000,从而产生签名的溢出和故障。

idk为什么有人在MIPS上使用add指令。普通的二进制添加指令称为addu

添加 - 捕获 - 签名的OPRFLOF FLOWS指令是add,即使您的数字已签名,也很少是您想要的。您最好忘记它存在并使用addu/addui

相关内容

  • 没有找到相关文章

最新更新