Can anyone help me debug my MIPS assembly code?

Fox5

Diamond Member
Jan 31, 2005
5,957
7
81
Ok, this is an assignment for my computer organization class, and we were required to:
Read in an integer less than 4096
And then print out the first 12 bits and their values, so for instance, 100 would display as
0 0
1 0
2 1
3 0
4 0
5 1
6 1
7 0
8 0
9 0
10 0
11 0

Here's my code so far
#Sets $s0 (the loop counter) equal to 0

li $s0, 0 #Set $s0 equal to 0

#Copies the user input from the temporary to $s1

add $s1, $t0, $zero #Store $t0 in $s1

#This is the start of a loop that should go through the loop 12 times.
#On each iteration it should check if the current value is odd or even (divide by 2 and check for remainder).
#Then it should cut off the end digit and output a 1 if there was a remainder.

loop: slt $t0, $s0, 12 #$t0 = 1 if loop counter is less than 12
bne $t0, 1, exit #Exit loop on the 12th iteration

#Load 2 into $t3 so it can be used for division. (no divide immediate command), then divide the number by 2.

li $t3, 2
add $t1, $s1, $zero #Store $s1 in temp $t1
div $t1, $t3 #Divide the integer by 2

#Load the remainder and see if it's greater than 0 (ie, there is a remainder).

mfhi $t4 #Stores the remainder in $t4
slt $t2, $zero, $t4 #Store 1 in $t2 if there is a remainder
sll $s1, $s1, 1 #Shifts the word right 1 bit


li $v0, 1 #System call code for print_int
add $a0, $s0, $zero #Load in current loop iteration
syscall #Print current loop iteration


li $v0, 4 #System call for print_str
la $a0, t #Load in tab
syscall #Print the tab


li $v0, 1 #System call for print_int
beq $t2, 1, printOne #If there is a remainder, go print 1, else print 0


li $a0, 0 #Load in the number 0
j Print #Print out the number

printOne: li $a0, 1 #Load in the number 1

Print: syscall #Print out the number

li $v0, 4 #System call for print_str
la $a0, n #Load in the new line
syscall #Print the new line

addi $s0, $s0, 1 #Increment the loop counter
j loop #Jump to the top of the loop

exit: li $v0, 10 #System call for exit
syscall #Exit

I left out some stuff at the beginning, but I'm pretty sure that's correct.
I'm not sure what's wrong with my code, but no matter what the input, I end up with 1 in the first bit, and 0's in all remaining bits. Anyone with a decent understanding of assembly code who can help me with this?
 

Fox5

Diamond Member
Jan 31, 2005
5,957
7
81
Oh, just wanted to note, I am aware of the discrepency between the sll (shift left logical) command and the comment next to it, I wasn't sure if maybe I was messing up the endian of the spim simulator (manual mentions it takes on the same endianess of the machine it's running on and not native mips), but neither a sll or a srl outputs any different results.
 

Markbnj

Elite Member <br>Moderator Emeritus
Moderator
Sep 16, 2005
15,682
14
81
www.markbetz.net
I'm going to watch this thread just to see if you find someone here that knows MIPS assembler.

Unfortunately, I ain't he.
 

Savarak

Platinum Member
Oct 27, 2001
2,718
1
81
its been nearly 8 years since i've played with MIPS assembler, all i know nowadays is IBM assembler ;)
 

Savarak

Platinum Member
Oct 27, 2001
2,718
1
81
Not sure why you SLL the $S1... you want to keep the number thats already been divided, otherwise you'd throw off the results
 

Fox5

Diamond Member
Jan 31, 2005
5,957
7
81
I did SLL on the $s1 since I wasn't sure of the endian of the simulator (it says it adopts whatever the endianess of the system it's running on is, not native MIPS), but both SRL and SLL give me the same results.
Additionally, I thought SRL was the same as divide by 2^n? Good point though, there is no reason I even have to touch the shift commands when I can just store the quotient. I'll try it that way.

This is really confusing me, no matter the input, the output is always 000000000001. I tried implementing the code with a bitwise ANDI with the value 1 (instead of checking for a remainder) but it produces the same results.
I also noticed a potential error, at the start of the loop I have:
slt $t0, $s0, 12
But slt is only supposed to operate on registers, whereas slti operates on immediates. Weird the compiler doesn't pick that up...it seems to function properly (the loop does complete 12 iterations) but I wonder if that could be causing some weird error.
 

Fox5

Diamond Member
Jan 31, 2005
5,957
7
81
Argh, storing the quotient instead of shifting right doesn't make any difference, neither did changing slt to slti.

I really don't understand why the loop evaluates to true on the first loop and false every subsequent time.
 

Fox5

Diamond Member
Jan 31, 2005
5,957
7
81
OMG, so many hours wasted over something so stupid.
The error was actually at the start of my program, I never stored the user input. Well, that explains why the output was always 1, it's because what was stored in the register at the time was a result of a slt.
 

akubi

Diamond Member
Apr 19, 2005
4,392
1
0
i dunno what pos simulator you're running it on... but it needs to be srl. no way it will work with sll.
but more importantly you should just bitwise and the last bit for a 0 or 1 instead of doing the div/mfhi/register shuffling

so basically you just and 1, print, srl, loop.
 

Fox5

Diamond Member
Jan 31, 2005
5,957
7
81
Originally posted by: akubi
i dunno what pos simulator you're running it on... but it needs to be srl. no way it will work with sll.
but more importantly you should just bitwise and the last bit for a 0 or 1 instead of doing the div/mfhi/register shuffling

so basically you just and 1, print, srl, loop.

Yeah, that's what I ended up doing. Error was not saving the user input into the correct register. Doh.