MIPS程序集将整数转换为二进制并读取1的个数? [英] MIPS Assembly converting integer to binary and reading the number of 1's?
问题描述
我正在编写一个程序,它从用户那里获取一个整数,然后输出它的二进制等价物中有多少个1。因此,首先我认为我需要将其转换为二进制,然后使用循环并检查所有32位,以确定有多少个1。
我已经浏览了几个小时,尝试了不同的方法来首先将整数转换为二进制。做这件事最好的方法是什么?有没有办法直接以二进制格式读取寄存器值,或者我需要先转换它?这是我到目前为止拥有的所有代码。
.data
EnterInteger: .asciiz "Enter an integer: "
.text
# Print the first message
li $v0, 4
la $a0, EnterInteger
syscall
# Prompt the user to enter the first integer
li $v0, 5
syscall
# Store the first integer in $t0
move $t0, $v0
以下是我到目前为止拥有的代码,但它不起作用。当我输入4673时,我应该得到&q;4&q;,但我只得到&q;1&q;
.data
Msg: .asciiz "Enter an integer: "
.text
# Print the first message
li $v0, 4
la $a0, Msg
syscall
# Prompt the user to enter the first integer
li $v0, 5
syscall
# Store the first integer in $t0
move $t0, $v0
addi $t3, $zero, 0
main:
bgt $t3, 32, exit
andi $t0, $v0, 1
bne $t0, $zero, count
count:
addi $t3, $t3, 1
addi, $t1, $zero, 1
# Shift to the next bit and then go back to main
srl $t0, $t0, 1
j main
exit:
# Tell the interpreter to get read to print an integer
li $v0, 1
add $a0, $zero, $t1
#Print the integer
syscall
# End the program
li $v0, 10
syscall
推荐答案
正如迈克尔所评论的,寄存器中的整数已经是二进制的。寄存器是一组32位。
至关重要的是,寄存器上的操作andi $t1, $v0, 1
和srl $v0, $v0, 1
以二进制方式工作。即and
得到的0或1是mod 2的值,右移1位除以2。
这是因为MIPS是一台二进制计算机,就像您可能为其学习汇编的每个超现实世界的ISA一样。具有&
和>>
操作的高级语言(包括C、Java和Python)也总是保证它们以二进制方式工作。(在非二进制计算机上,例如,在三进制计算机上,实现x & y
的这些语义将涉及到转换为基数位数组并手动执行逻辑,然后再转换回来。)
divu
)或余数来删除或分离最低的基数10位数字。或者如果基数是2的幂,如基数16,则移位4位,或与0x0f
(取低4位,即0b1111)。其他基数中的输入/输出涉及将(二进制)整数从/转换为表示另一个基数中的数字的ASCII数字字符串。Mars/spim read_int调用(syscall
,$V0=5)为您完成了这项任务,就像C库函数scanf或printf一样。要手动完成此操作,您可以执行类似total = total * 10 + digit
的操作,其中digit
类似于ascii_char - '0'
。或对于输出,重复除以10以10为模,以得到以10为基数的数字,从最低位开始。
ASCII十进制或十六进制字符串是数字的序列化格式,而不是它们在计算机中的存在方式(作为字符串,而不是整数)。
人口数
一次循环一个比特,提取并添加低位,这是计算设置比特数量的一种简单但往往效率低下的方法。尽管如此,简单对于第一次尝试是好的;选择andi
和srl
作为前面的示例是一个提示。
How to count the number of set bits in a 32-bit integer?中显示了一些速度更快的bithack,但对于MIPS,这意味着要生成大量单独的32位常量,每个常量需要2条指令。您可以执行两个Swar加宽步骤,然后循环4位和的组,作为中间点。
Count bits 1 on an integer as fast as GCC __builtin__popcount(int)显示了一种计算n &= n-1
到clear the lowest set bit的迭代次数的方法,如果只设置了几个位,即使它们不在寄存器的底部,该方法也会更快。
这篇关于MIPS程序集将整数转换为二进制并读取1的个数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!