MIPS branching always the same - mips

So with this MIPS code I'm trying to get a users input of a tree size they would like and the output is the cost. 199 for > 8, 99 >= 6, 69 >= 3, 39 >= 0, and just a phrase saying positive only for a negative input.
My problem is that no matter the input, the program always spits out 69, whats wrong?
#data declarations: declare variable names used in program, storage allocated in RAM
.data
msg1: .asciiz "Enter the height of a tree to purchase: "
msg21: .asciiz "The cost: "
msg22: .asciiz " dollars\n"
msg3: .asciiz "\n"
msgNeg: .asciiz "Please enter a positive integer for the tree height.\n"
big: .word 8
med: .word 6
small: .word 3
negative: .word 0
#The program begins after .text
.text
main:
#Prints first line and receives input
la $a0, msg1
li $v0, 4
syscall
li $v0, 5
syscall
la $a0, msg3
li $v0, 4
syscall
#Stores user input in parameter variable
move $a0, $v0
#Calls cost function to determine cost
addi $sp, $sp, -4
sw $ra, 0($sp)
jal cost
lw $ra, 0($sp)
addi $sp, $sp, 4
#stores returned value to temporary register
move $t0, $v0
#Prints out the cost of the tree
la $a0, msg21
li $v0, 4
syscall
move $a0, $t0
li $v0, 1
syscall
la $a0, msg22
li $v0, 4
syscall
#return
jr $ra
cost:
#finds the range of the user value
la $t6, small
lw $t7, 0($t6)
bge $a0, $t7, smTree
nop
la $t6, med
lw $t7, 0($t6)
bge $a0, $t7, medTree
nop
la $t6, big
lw $t7, 0($t6)
bgt $a0, $t7, bigTree
nop
la $t6, negative
lw $t7, 0($t6)
blt $a0, $t7, negTree
nop
#else statement, returns 39
li $v0, 39
jr $ra
bigTree:
#first branch, returns 199
li $v0, 199
jr $ra
medTree:
#second branch, returns 99
li $v0, 99
jr $ra
smTree:
#third branch, returns 69
li $v0, 69
jr $ra
negTree:
#fourth branch, returns a phrase
la $a0, msgNeg
li $v0, 4
syscall
jr $ra

When you're reading the user's number:
li $v0, 5
syscall
la $a0, msg3
li $v0, 4
syscall
#Stores user input in parameter variable
move $a0, $v0
$v0 will no longer hold the user's value. It has been overwritten with 4, which corresponds to the case that returns a cost of 69. You'll have to copy $v0 to another temporary register right after syscall 5.
Also, the logic of cost is currently like this:
if (value >= 3)
return 69;
if (value >= 6)
return 99;
if (value >= 8)
return 199;
So any value >= 3 will return 69, and the larger cases will never be checked. You can just change the order to fix it:
if (value >= 8)
return 199;
if (value >= 6)
return 99;
if (value >= 3)
return 69;

Related

Getting Memory out of bounds exception while running code in QTSPIM

I am trying an array to save i * j values and print the values from array.
I have two loops loop1, loop2, where loop1 takes i and loop2 takes on j.
I am trying to save the i * j in a myarray which is space datatype.
I am getting exception Memory address out of bounds and unable to find whats the error.
.data
myarray: .space 10000
n: .word 1
space_line: .asciiz " "
new_line: .asciiz "\n"
.text
.globl main
main:
lw $a0, n
la $a1, myarray
li $a2, -1 #row
li $t0, 0
li $t2, 0
loop1:
addi $a2, $a2,1
bge $a2, $a0, print_loop
li $a3, 0 #column
j loop2
loop2:
bge $a3, $a0, loop1
#multiply a2 and a3
mul $t1, $a2, $a3
sw $t1, 0($a1)
addu $a1, $a1,4
addi $a3, $a3,1
j loop2
print_loop:
mul $t3, $a0, $a0
bge $t0, $t3, exit
li $v0, 4
lw $a0, myarray($t2)
syscall
li $v0, 4
lw $a0, space_line
syscall
rem $t4, $t3, $a0
beqz $t4, newline
addu $t2, $t2, 4
addi $t0, $t0, 1
j print_loop
newline:
li $v0, 4
lw $a0, myarray($t2)
syscall
exit:
# Done, terminate program.
li $v0, 10
syscall # all done!
.end main
For n =4,i am expecting the output in console as
0 0 0 0
0 1 2 3
0 2 4 6
0 4 8 12
You can find this problem by single stepping in the debugger.  Start with the smallest possible input, like n=1 as you're showing.  After each instruction, verify that it did what you want, and that it didn't do anything else except what you wanted.
Here's a hint: Pay attention to the difference between la and lw.  Also, If you want to put syscalls in the middle of your code or loops, then avoid the $a0 and $v0 registers for your own variables — just makes things easier/better.

How to count the number of spaces in MIPS?

I need to write a program in which the output will be the number of sentences and average number of words. The code is working perfectly for counting the sentences, but for the second task, it doesn't work. I'm using branch if equal with the current char and the register in which I've declared the ascii value for space which is 32. With this code, the output for the average words is the total number of characters from the whole input. I can't understand how it can count every character when the beq is clearly incorrect. (I've also tried with emptySpace: .asciiz " ", but it's not working)
This is what I got so far:
.data
str_input: .space 256
dot: .asciiz "."
msg1: .asciiz "Number of sentences: "
msg2: .asciiz "\nAverage number of words: "
.text
li $v0, 8 #read string
la $a0, str_input #address of str_input vo $a0
li $a1, 256 #256 max
la $a2, dot
lb $a2, 0($a2)
li $a3, 32
syscall
addi $t4, $zero, 0 #counter for words
addi $t5, $zero, 0 #counter for sentences
or $t0, $a0, $zero #$t0 pointer to array
start:
lb $t1, 0($t0) #$t1 current char
beqz $t1, end
jal check
addiu $t0, $t0, 1
j start
chech:
beq $t1, $a2, IsDot
beq $t1, $a3, IsEmptySpace
IsDot:
addi $t5, $t5, 1
jr $ra
IsEmptySpace:
addi $t4, $t4, 1
jr $ra
end:
la $a0, msg1 #address of msg1 in $a0
li $v0, 4 #load string in $v0
syscall
add $a0, $t5, $zero
li $v0, 1
syscall #print number of sentences
addi $t4, $t4, 1 #add the last word
div $t4, $t5 #divide number of words with number of sentences
mflo $t6
la $a0, msg2 #address of msg2
li $v0, 4 #load string in $v0
syscall
add $a0, $t6, $zero
li $v0, 1
syscall

Replacing repeated consecutive characters with X

I have some trouble with my code.
I need this in/output on the console.
Input String : aaabcccdeefggg
Input char: X
Replace:XXXbXXXdXXfXXX <--I want this output
But i get this output-->XXabXXcdXefXXg
I dont know where the bug is, i am searching for hours for this bug.
.data
enterString: .asciiz "Input String > "
enterChar: .asciiz "Input char> "
changedString: .asciiz "\nReplace: "
numberOfAdditions: .asciiz "\Total Replaces: "
userInput: .space 555
.text
main:
li $v0, 4
la $a0, enterString
syscall
li $v0, 8
la $a0, userInput
li $a1, 554
syscall
li $v0,4
la $a0,enterChar
syscall
li $v0,12
syscall
move $t5,$v0 # $t0 = character to be replaced
li $t0, 0
li $t1, 1
j findDoubleCharacters
findDoubleCharacters:
lbu $s0, userInput( $t0 )
lbu $s1, userInput( $t1 )
addi $t0, $t0, 1
addi $t1, $t1, 1
beq $s0, $s1, found
beq $s1, 0, end
j findDoubleCharacters
found:
subi $t0, $t0, 1
subi $t1, $t1, 1
sb $t5, userInput($t0)
addi $s2, $s2, 1
j findDoubleCharacters
end:
li $v0, 4
la $a0, changedString
syscall
li $v0, 4
la $a0, userInput
syscall
li $v0, 4
la $a0, numberOfAdditions
syscall
li $v0, 1
move $a0, $s2
syscall
...

MIPS Help. Load Byte error. Address out of range

I am trying to add numbers that are in base 5.
Im supposed to prompt the user for 2 separate base 5 number in the form XXXXXX.XXXXX, and then add them.
My current problem is that I am getting an error when I am loading the last digit into a register, so I can start the calculation.
please help! Thanks
.data
str: .space 13 # XXXXXX.XXXXX hold 12 chars + 0x00
str2: .space 13
sum: .space 14
printstr: .space 13
printstr2: .space 13
printsum: .space 14
message1: .asciiz "Enter a base 5 number A: "
message2: .asciiz "Enter a base 5 number B: "
message3: .asciiz "Sum of A and B: "
newline: .asciiz "\n"
.text
main:
#get number A
li $v0, 4
la $a0, message1
syscall
li $v0, 8
li $a1, 13
la $a0, str
syscall
li $v0, 4
la $a0, newline
syscall
#get number B
li $v0, 4
la $a0, message2
syscall
li $v0, 8
li $a1, 13
la $a0, str2
syscall
li $v0, 4
la $a0, newline
syscall
#pointer to input string A
la $s1, str
addi $s1, $s1, 12
#pointer to input string A
la $s2, str2
addi $s2, $s2, 12
#pointer to sum
la $s3, sum
addi $s3, $s3, 13
#other variables
li $t0, 0 # inital carry is 0
li $t1, 1 # counter for looping through string
li $t2, 5 # base 5
loop:
lb $t3, ($s1) ############################# PROBLEM HERE######
lb $t4, ($s2)
beq $t3, '.', next
beq $t4, '.', next
subi $t3, $t3, 0x30
subi $t4, $t4, 0x30
add $t5, $t3, $t4
add $t5, $t5, $t0
div $t5, $t2
mflo $t0
mfhi $t5
addi $t5, $t5, 0x30
sb $t5, ($s3)
subi $s1, $s1, 1
subi $s2, $s2, 1
subi $s3, $s3, 1
addi $t1, $t1, 1
ble $t1, 13, loop
addi $t0, $t0, 0x30
sb $t0, ($s3)
next:
subi $s1, $s1, 1
subi $s2, $s2, 1
#subi $s3, $s3, 1
addi $t1, $t1, 1
j loop
PRINT: #print the sum
exit:
li $v0, 10
syscall
You set up $s1 to point past str and decrement it backwards. Your loop: termination is the ble $t1,13,loop. When that completes, $s1 is pointing to the start of the .data section (i.e. 0x10010000).
But, then, you "fall through" to next: [probably wrong] and decrement $s1 so it has the value 0x1000ffff. Then, you do j loop so the fetch is now coming from an address one byte below the start of the .data segment (i.e. memory that does not exist)
That's the source of the crash. You probably need a jump inst after the ble to continue on to some other code.
But, also, when you do beq $t3,'.',next you go to next: and decrement both pointers. Unless you restrict your input there is no guarantee that both $s1 and $s2 both point to '.' at the same time, so you only want to decrement one of them. (e.g. suppose you had str: 12.3 and str2: 123.41)
So, you may need some code to align the two numbers with respect to their decimal points beforehand.

function in mips that calculates the absolute value [duplicate]

This question already has answers here:
Integer absolute value in MIPS?
(5 answers)
Closed 2 years ago.
hello i have an exercise in mips that must call a function to calculates the absolute value of a number
i have write 2 codes but if you have any other solution write it
.data
message:.asciiz "give number: "
.text
main:
li $v0, 4
la $a0, message
syscall
li $v0, 5
syscall
add $t1, $v0, $zero
jal absolute
add $v0,$t2,$zero
li $v0, 1
syscall
li $v0, 10
syscall
absolute: ori $t2,$t1,0 #copy r1 into r2
slt $t3,$t1, $zero #is value < 0 ?
beq $t3,$zero,gg #if r1 is positive, skip next inst
sub $t2,$zero, $t0 #r2 = 0 - r1
jr $ra
gg:
#t2
and the second code is this
.data
question: .asciiz "give number"
.text
main:
li $v0, 4
la $a0, question
syscall
li $v0, 5
syscall
jal absolute
li $v0, 1
syscall
li $v1, 1
syscall
li $v0, 10
syscall
absolute:
slti $t0,$a0,0
bne $t0,$zero,g1
add $v0,$a0,$zero
jr $ra
g1:
sub $t2,$a0,$a0
sub $v1,$t2,$a0
j absolute
Try this:
.data
message: .asciiz "Enter the number: "
.text
.globl main
main:
# print message
li $v0, 4
la $a0, message
syscall
# read integer
li $v0, 5
syscall
slt $t0, $v0, $0 # $t0 = ( $v0 < 0 ? 1 : 0 )
bne $t0, $0, NEGATIVE # if($t0 != 0) goto NEGATIVE
j POSITIVE # goto POSITIVE (and dose nothing)
NEGATIVE:
# ~$v0 + 1
nor $v0, $v0, $0 # NOR with zero = NOT
addi $v0, $v0, 1 # $v0 =+ 1
POSITIVE:
# print $v0
move $a0, $v0
li $v0, 1
syscall
# print new line '\n'
li $v0, 11
addi $a0, $0, 10
syscall
jr $ra
Test:
Enter the number: 10
10
Enter the number: -5
5