I am creating a program for a user to enter an integer and then check each bit and count how many 1's is in it's binary value. So if I input 4673 I should get "4" as an output because there is 4 ones. This is the code I have below, for some reason I am only getting "0" as an output. My guess is I am not properly loading each bit with the "andi" and "srl". I check it step by step and when it comes to andi and srl $t0 never holds a value of 1, so I must not be shifting bit by bit?
.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, 1
main:
bgt $t3, 31, exit
addi $t3, $t3, 1
andi $t0, $v0, 1
srl $t0, $t0, 1
bne $t0, $zero, count
j main
count:
addi, $t1, $t1, 1
# Shift to the next bit and then go back to main
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
CodePudding user response:
You've got this instruction andi $t0, $v0, 1
in your loop. But $v0
never changes within the loop, so you're always getting the same value. And regardless of whether that values was 0 or 1, it's going to be 0 after the srl
on the following line.
The whole bit-counting loop could be replaced by something like this:
li $t1, 0 # number of 1-bits
count_ones:
andi $t2, $t0, 1 # t2 = input & 1
addu $t1, $t1, $t2 # count = (input & 1)
srl $t0, $t0, 1 # input >>= 1
bne $t0, $zero, count_ones # loop until no 1-bits left
Note that there are more efficient ways of doing this, without any loops at all. See How to count the number of set bits in a 32-bit integer?