Memory address out of bounds error in MIPS but works in a different function - mips

I am making a program in MIPS that will compare two strings but I can't seem to access the proper locations. I have a function that calculates the lenght of the strings which works fine, but when I try to use a different function (in this case its just a test to see if it works), it says that i'm acessing the wrong memory. I am using QTSpim to test it. The function that works is the duzinaStringa, the one that does not is the krajStringa. Currently it's just trying to print out the first character of the string so I can make sure it works
.text
krajStringa:
li $v0,0
li $t0,0 #brojac1
move $t2, $a0 #adresa prvog
move $t3, $a1 #adresa drugog
lb $a0,0($t2)
li $v0,4
syscall
jr $ra
duzinaStringa:
move $t1,$a0
li $t0,0
petlja:
lb $t2,0($t1)
beqz $t2,krajDuzine
addi $t1,$t1,1
addi $t0,$t0,1
j petlja
krajDuzine:
addi $t0,$t0,-1
move $v0,$t0
jr $ra
main:
la $a0,str1
li $v0, 4
syscall
la $a0, arr
li $a1,200
li $v0, 8
syscall
la $a0,str1
li $v0, 4
syscall
la $a0, arr2
li $a1,200
li $v0, 8
syscall
la $a0,arr
jal duzinaStringa
move $a2,$v0
la $a0,arr2
jal duzinaStringa
move $a3,$v0
la $a0,arr
la $a1,arr2
jal krajStringa
li $v0,10
syscall
.data
arr: .space 200
arr2: .space 200
str1: .asciiz "Unesi string: \n"

As #ErikEidt pointed out, I used the wrong system call when printing the first character of a string.

Related

MIPS - Prints the input next to output

I'm learning MI trying to write a factorial program in MIPS Assembly code for which
3! = 6 (my output shows it 36)(input next to output)
4! = 24(my output shows it as 424)
Here is my code. What should I do to get rid of printing the input?
.data
num: .asciiz "\nPlease enter a number: "
num2: .asciiz"\nPlease give your second number : "
respon: .asciiz "\nThe factorial of the entered number is: "
nl: .asciiz"\n"
.text
fact:
beqz $a0,return1
li $v0, 1
li $t0, 1
fact_loop:
bgt $t0, $a0, end_fact_loop
mul $v0, $v0, $t0
addi $t0, $t0, 1
j fact_loop
end_fact_loop:
jr $ra
return1:
li $v0, 1
jr $ra
main:
li $v0, 4
la $a0, num
syscall
li $v0, 5
syscall
move $t0, $v0
li $v0, 4
la $a0, respon
syscall
li $v0, 1
move $a0, $t0
syscall
jal fact
move $t0, $v0
li $v0, 1
move $a0, $t0
syscall
li $v0, 4
la $a0, nl
syscall
################################
li $v0, 4
la $a0, num2
syscall
li $v0, 5
syscall
move $t0, $v0
li $v0, 4
la $a0, respon
syscall
li $v0, 1
move $a0, $t0
syscall
jal fact
move $t0,$v0
li $v0, 1
move $a0, $t0
syscall
li $v0, 10
syscall
To get rid of printing the input you have to remove the syscall you are issuing to print them.
That is, before jal-ing fact (both times) you are issuing these instructions:
li $v0, 1
move $a0, $t0
syscall
Just, remove the first and third instruction and keep the move as you use it on your fact routine:
move $a0, $t0
A few suggestions:
Add a comment to each functional chunk of code.
Use a single-step to debug so you can see what's happening where.
Simplify the code to a minimal failing example. If you have two chunks of code both exhibiting the same problem, remove one of them and focus on the first without distractions and noise from the second.
Prune unnecessary code. For example, the return1: block and beqz $a0,return1 are superfluous because the main factorial loop will exhibit the same behavior automatically -- you don't need to handle $a0 == 0 specially.
Having followed these tips, I wound up with the following program:
.data
num: .asciiz "\nPlease enter a number: "
num2: .asciiz "\nPlease give your second number : "
respon: .asciiz "\nThe factorial of the entered number is: "
nl: .asciiz "\n"
.text
fact:
li $v0, 1
li $t0, 1
fact_loop:
bgt $t0, $a0, end_fact_loop
mul $v0, $v0, $t0
addi $t0, $t0, 1
j fact_loop
end_fact_loop:
jr $ra
main:
# print prompt "Please enter a number: "
li $v0, 4
la $a0, num
syscall
# get user input for first fact call
li $v0, 5
syscall
move $t0, $v0
# call fact(n)
move $a0, $t0
jal fact
move $t0, $v0
# print "factorial is..."
li $v0, 4
la $a0, respon
syscall
# print the result of fact(n)
li $v0, 1
move $a0, $t0
syscall
# print newline
li $v0, 4
la $a0, nl
syscall
# exit program
li $v0, 10
syscall
The problem of double-printing is caused by this code:
li $v0, 1
move $a0, $t0
syscall
The move $a0, $t0 is necessary to set up the fact call, but we don't want li $v0, 1 and syscall, which prints the argument without a newline before the result of fact, causing your unwanted output.
A good technique to prevent this in the future is ensuring your argument set-up for the function call to fact happens right before the jal.
I'll leave it as an exercise to adapt this to your second chunk of code, which has the same extra syscall to service 1 (print integer).

Swap procedure not working in MIPS

The objective of this program is to swap two numbers without using temporary variables. I came up with a solution by just using math but when I assemble, the numbers don't swap and I can't figure out why. Can anyone explain my mistake?
.text
main:
la $a0,n1
la $a1,n2
jal swap
li $v0,1 # print n1 and n2; should be 27 and 14
lw $a0,n1
syscall
li $v0,11
li $a0,' '
syscall
li $v0,1
lw $a0,n2
syscall
li $v0,11
li $a0,'\n'
syscall
li $v0,10 # exit
syscall
swap: #this is my code and where I'm having problems
sub $a0, $a0, $a1
add $a1, $a1, $a0
sub $a0, $a1, $a0
jr $ra
.data
n1: .word 14
n2: .word 27

Mips help syscall

I do not understand why when Mars runs the function it prints the numbers in the array but not the new line. Can you help me?
stampaC:
lw $t6,0($a1)
#Stampo c[i]
li $v0, 1
move $a0, $t6
syscall
li $v0, 4
la $a0, a_capo
syscall
addi $a1,$a1, 4
addi $a3,$a3, 1 #i++
bne $a3, 10, stampaC #Continua fino a quando i=10
jr $ra
Assuming you are trying to print a newline with the a_capo literal, I guess you are not defining correctly that literal.
In your .data section you should write
a_capo: .asciiz "\n"
Then, this snippet should print a newline:
li $v0, 4
la $a0, a_capo
syscall

What does the following QtSPIM/MIPS code do

What does the following QtSPIM/MIPS code do. Describe by referring to the functions of various blocks of the code (Block1, Block2, …).
Answer the questions in front of certain instructions.
Block1:
.text
main:
li $s4, 0
la $a0, input
li $v0, 4
syscall
li $v0, 5
syscall
move $t0, $v0 #Why do we need this?
Block2:
la $a0, output
li $v0, 4
syscall
move $a0, $t0
li $v0, 1
syscall
la $a0, newline # How will the output change if newline is replaced by newspace defined as “ “?
li $v0, 4
syscall
Block3:
Do:
move $a0, $s4
li $v0, 1
syscall
la $a0, newline
li $v0, 4
syscall
slt $s1, $s4, $t0
addi $s4, $s4, 1
bgt $s1, $zero, Do # Why can’t we use “beq $s1, 1, Do “?
Block4:
Exit:
li $v0, 10
syscall
.data
input: .asciiz "Input a number: "
output: .asciiz "Let me count till "
newline: .asciiz "\n "
So I need help with identifying what the code does... I have the concept I just want o make sure Im properly figuring this out... So I have this so far:
move $t0, $v0 #Why do we need this? --- to store number in t0
la $a0, newline # How will the output change if newline is replaced by newspace defined as “ “?
--- load address of string to be printed into $a0 and adds the space if replaced by newspace
the last one I cant quite figure out...

Take user input and print a floating point array in MIPS

I need to take input from the user a floating point array and then print it. I tried the following code:-
.text
.globl main
main:
la $s0,size
lw $s1,0($s0) # size in $s1
ori $s2,$zero,0 # i in $s2
la $s3,arr # arr in $s3
li $v0,4
la $a0,msg1
syscall
L1:
beq $s2,$s1,DONE
li $v0,6
syscall
swc1 $f0,0($s3)
j UPDATE
UPDATE:
addi $s3,$s3,4
addi $s1,$s1,1
j L1
DONE:
li $v0,4
la $a0,msg2
syscall
la $t0,arr
ori $t1,$zero,0
L2:
beq $t1,$s1,EXIT
lwc1 $f20,0($t0)
li $v0,2
mov.s $f12,$f20
syscall
addi $t0,$t0,4
addi $t1,$t1,1
j L2
EXIT:
li $v0,10
syscall
.data
size: .word 9
arr: .float 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
msg1: .asciiz "Enter the elements:-"
msg2: .asciiz "The elements are:-"
When i give the input, there is a runtime exception 'invalid float input' at syscall 6. Please help!!!
I guess you are using , as the decimal point instead of ..
E.g.: instead of entering 3.14159 you are entering 3,14159 which is not expected at least by MARS.
Aside from that, I think the line addi $s1,$s1,1 in your code should be addi $s2,$s2,1, as you seem to be using $s2 to hold the current value of your index counter.