MIPS instruction `load word` not loading word into the register - arrays

I am writing a program that given an array, it prints out array value and swap two elements of choice by users. This is the code:
# Declare main as a global function
.globl main
# Declare the data
.data
list:
.align 4 # Forces a word to line up at boundary/4
.word 5, 17, 43, 22, 120, 3 # A six-element array
endList:
space:.asciiz " "
newLine: .asciiz "\n"
msg1:.asciiz "Array is: "
msg2:.asciiz "Enter fisrt index to swap: "
msg3:.asciiz "Enter second index to swap: "
msg4:.asciiz "Array after swapping is: "
#.text assembler directive to place the code
.text
# Start the program at main
main:
la $s1, list # Load beginning address of array
into register $s1
la $s2, endList # Load end address of array into register $s2
la $a0, msg1 # Load address of message string into $a0
li $v0, 4 # Load print string system call code into $v0
syscall # System call to print
jal printLoop
jal swap
# Exit
li $v0, 10
syscall
printLoop:
beq $s1, $s2, printDone # Check when array end, go to done
lw $a0, ($s1) # Load word at address of $s1 into $a0
li $v0, 1 # Load print integer system call code
into $v0
syscall # System call to print number
la $a0, space # Load address of space stringinto $a0
li $v0, 4 # Load print string system call code into $v0
syscall # System call to print a space
addi $s1, $s1, 4 # Advance array pointer to the next element
j printLoop # Loop back to next element
printDone:
j $ra
swap:
la $a0, newLine # Print a new line
li $v0, 4
syscall
la $a0, msg2 # Print a message to ask for first index to swap
li $v0, 4
syscall
li $v0, 5 # Get user input, save into $s3
syscall
addi $s3, $v0, 0
la $a0, msg3 # Print a message to ask for second index to swap
li $v0, 4
syscall
li $v0, 5 # Get user input, save into $s4
syscall
addi $s4, $v0, 0
sll $t0, $s3, 2 # Multiply first index by 4 to get its offset
add $t0, $s1, $t0 # Get the address of the first index
sll $t1, $s4, 2 # Multiply second index by 4 to get its offset
add $t1, $s1, $t1 # Get the address of the second index
lw $t2, ($t0) # Load first number at address contained in $t0 into $t2
lw $t3, ($t1) # Load second number at address contained in $t1 into $t3
sw $t2, ($t1) # Store first number into address of second number
sw $t3, ($t0) # Store second number into address of first number
move $a0, $t0
li $v0, 4
syscall
move $a0, $t1
li $v0, 4
syscall
j $ra
When I step through the code using QtSpim, these lines seem to be giving problems:
lw $t2, ($t0)
lw $t3, ($t1)
The values in $t2 and $t3 should be integer values given by the array. For example, if user specifies index 1 and 2, values in $t2 and $t3 should be 5 and 17. Instead it showed weird numbers: 1634890305 and 1936269433 (decimal) in my version.
What is going wrong? I would appreciate any help!

Printloop changes $s1, so when swap uses it, it points at the list end.

Related

Can't figure out how to retrieve values from heap in MIPS (MARS)

I am new to using dynamic memory in mips. I have to create a program that takes 2 integers from the user, find the positions where the binary forms of those numbers have a 1, print the positions for each number/set (For example: 1000 1001 1100 0000 0000 0010 1000 1110 corresponds to the set: {2, 3, 4, 8, 10, 23, 24, 25, 28, 32}). Then take another integer from the user and see if it is one of the positions in either set. Eventually I will have to find the union and intersection of the two sets but I am not there yet.
So I printed out both sets normally but I also saved them to heap because I figured that would be the only way to be access them later to see if the next number is a member of either set. My problem is that, for the life of me, I can't figure out how to retrieve the sets from heap to use them again.
My code is below. I know it is kind of long so for reference, I store them in dynamic memory in the SetOne and SetTwo functions, and I am trying to retrieve them in the ElementSetOne and ElementSetTwo functions. Sorry if I'm not being descriptive enough, I'm still very new to StackOverflow. Thanks.
.data #Data section
Prompt1: .asciiz "\nEnter first number: "
Prompt2: .asciiz "\nEnter second number: "
Result1: .asciiz "\nMembers of Set 1: "
Result2: .asciiz "\nMembers of Set 2: "
Prompt3: .asciiz "\nEnter an element to find: "
Result3: .asciiz "\nIt is a member of set 1"
Result4: .asciiz "\nIt is not a member of set 1"
Result5: .asciiz "\nIt is a member of set 2"
Result6: .asciiz "\nIt is not a member of set 2"
Result7: .asciiz "\nUnion of the sets: "
Result8: .asciiz "\nIntersection of the sets: "
Prompt4: .asciiz "\nDo you want to compute set functions again? "
.globl main
.text #Code section
main:
li $v0, 4 #system call code for Print String
la $a0, Prompt1 #load address of Prompt1 into $a0
syscall #print the Prompt1 message
li $v0, 5 #system call code for Read Integer
syscall #reads the value of 1st integer into $v0
move $t0, $v0 #move first integer to $t0
li $v0, 4 #system call code for Print String
la $a0, Prompt2 #load address of Prompt2 into $a0
syscall #print the Prompt2 message
li $v0, 5 #system call code for Read Integer
syscall #reads the value of second integer into $v0
move $t1, $v0 #move second integer to $t1
First:
li $v0, 4 #System call code for Print String
la $a0, Result1 #load address of Print into $a0
syscall #print the string
li $v0, 9 #syscall for dynamic memory allocation (sbrk)
li $a0, 80
syscall
move $s0, $v0
li $t4, 0 #sets count to 0
FirstMask:
beq $t0, 0, Second #if first set is done, go to second
andi $t6, $t0, 1 #first number and 1
addi $t4, $t4, 1 #increase count by 1
beq $t6, 1, SetOne #if and with 1, go to SetOne
srl $t0, $t0, 1 #shift number right 1 position
j FirstMask #restart loop
SetOne: #STORE SET 1
sw $t4, 0($s0) #store position in memory
add $s0, $s0, 4 #increment memory
li $v0, 1 #system call code for Print Integer
move $a0, $t4 #move value to be printed to $a0
syscall #print the the count positiom
li $v0, 11 #syscall number for printing character
li $a0, 32 #move ascii code for space in $a0
syscall #print blank space
srl $t0, $t0, 1 #shift input number right 1 position
j FirstMask
Second:
li $v0, 4 #System call code for Print String
la $a0, Result2 #load address of Print into $a0
syscall #print the string
li $v0, 9 #syscall for dynamic memory allocation (sbrk)
li $a0, 80
syscall
move $s1, $v0
li $t4, 0 #reset count to 0
SecondMask:
beq $t1, 0, Element #if number is done go to next step
andi $t6, $t1, 1 #and input with 1
addi $t4, $t4, 1 #increase count by 1
beq $t6, 1, SetTwo #if and with 1, save position number
srl $t1, $t1, 1 #shift right 1 position
j SecondMask
SetTwo: #STORE SET 2
sw $t4, 0($s1) #store position in memory
add $s1, $s1, 4 #increment memory
li $v0, 1 #system call code for Print Integer
move $a0, $t4 #move value to be printed to $a0
syscall #print the count
li $v0, 11 #syscall number for printing character
li $a0, 32 #move ascii code for space into $a0
syscall #print blank space
srl $t1, $t1, 1 #shift right 1 position
j SecondMask
Element:
li $v0, 4 #System call code for Print String
la $a0, Prompt3 #load address of Print into $a0
syscall #print the string
li $v0, 5 #system call code for Read Integer
syscall #reads the value of 1st integer into $v0
move $t2, $v0 #move first integer to $t2
ElementSetOne: #RETRIEVE SET 1
lw $t3, 0($s0) #load first number from memory into $t3
beq $t2, $t3, InSetOne #if element is in memory, go to InSetOne
bgt $s0, 40, NotSetOne #if element isnt in entire array, go to NotSetOne
addi $s0, $s0, 4 #increment memory by 4
j ElementSetOne
InSetOne:
li $v0, 4 #System call code for Print String
la $a0, Result4 #load address of Print into $a0
syscall #print the string
j ElementSetTwo
NotSetOne:
li $v0, 4 #System call code for Print String
la $a0, Result5 #load address of Print into $a0
syscall #print the string
j ElementSetTwo
ElementSetTwo: #RETREIVE SET 2
lw $t3, 0($s1) #load first number from memory into $t3
beq $t2, $t3, InSetTwo #if element is in memory, go to InSetOne
bgt $s1, 40, NotSetTwo #if element isnt in entire array, go to NotSetOne
addi $s1, $s1, 4 #increment memory by 4
j ElementSetTwo
InSetTwo:
li $v0, 4 #System call code for Print String
la $a0, Result5 #load address of Print into $a0
syscall #print the string
j Exit
NotSetTwo:
li $v0, 4 #System call code for Print String
la $a0, Result6 #load address of Print into $a0
syscall #print the string
j Exit
Exit:
li $v0, 10 #terminate program
syscall #return control to the system
Update: I am taking programming in C next semester so I don't know very much about the language. Essentially, my problem is that I stored a set of numbers into heap. And I can't figure out how to retrieve them now.
I know they were successfully stored because when I look in the heap section while running the program in MARS, I can see them being stored one by one. I'm just trying to retrieve all the numbers for each set now, but what I have just returns 0. So I'm thinking I must be using the wrong address or I'm missing a step somewhere.
I think this is all the code that is relevant:
li $v0, 9 #syscall for dynamic memory allocation (sbrk)
li $a0, 80
syscall
move $s0, $v0
#Theres a loop here to find the values of $t4
SetOne: #STORE SET 1
sw $t4, 0($s0) #store values in $s0
add $s0, $s0, 4 #increment memory
li $v0, 9 #syscall for dynamic memory allocation (sbrk)
li $a0, 80
syscall
move $s1, $v0
#Theres another loop here to find different values of $t4
SetTwo: #STORE SET 2
sw $t4, 0($s1) #store position in memory
add $s1, $s1, 4 #increment memory
#Then later on I want to retrieve these values so i can use them in other loops
ElementSetOne:
lw $t3, 0($s0) #load first number from memory into $t3
beq $t2, $t3, InSetOne #if element is in memory, go to InSetOne
bgt $s0, 40, NotSetOne #if element isnt in entire array, go to NotSetOne
addi $s0, $s0, 4 #increment memory by 4
j ElementSetOne. #loop
ElementSetTwo: #RETREIVE SET 2
lw $t3, 0($s1) #load first number from memory into $t3
beq $t2, $t3, InSetTwo #if element is in memory, go to InSetOne
bgt $s1, 40, NotSetTwo #if element isnt in entire array, go to NotSetOne
addi $s1, $s1, 4 #increment memory by 4
j ElementSetTwo #loop

MIPS Problem in printing the array and get the third element multiply to 4

I'm new to MIPS and I'm stuck in the printing array and the function also kinda mess up
This is my code, it works for the get input I guess but after that, they display the array and have error.
This is the question:
Prompts the user to input an integer number between 1 and 10 using the console
Write a function to initialize an array of 5 elements with the value entered by the user. This function must include the following
A loop
A branch
Write a function to multiply the third element of the array initialized above by the number 4.
Write a function to print all the elements of the array to the console. The third element must be 4 times the other elements. This function must include the following
A loop
A branch
Your code must have three separate functions (in addition to the main section) and function calls
Function to initialize the array
Function to multiply the third element of the array by the user input number
Function to print the arrays to screen.
.data
array: .space 20
prompt: .asciiz "Input 5 integers\n"
.align 3
.text
main:
li $v0, 4
la $a0, prompt
syscall
loop:
beq $t0, 20, exit
li $v0, 5
syscall
sw $v0, array($t0)
add $t0, $t0, 4 #increase index
j loop
exit:
jr $ra
print_loop:
la $t1, array # get array address
li $t2, 0 # set loop counter
beq $t2, 5, exit_print_loop
lw $a0, ($t1) # print value at the array pointer
li $v0, 1
syscall
addi $t2, $t2, 1 # advance loop counter
addi $t1, $t1, 4 # advance array pointer
j print_loop # repeat the loop
exit_print_loop:
li $v0, 10
This is my code that I made and it works perfectly for my test. Thank you!
.data
array: .space 20 #create an array for 5 integer
prompt1: .asciiz "Input 5 integers from 1 to 10 \n"
prompt2: .asciiz "\nThe array is: \n"
prompt3: .asciiz "Third element times 4 is: "
newLine: .asciiz "\n"
.align 3
.text
main:
#prompt the user input
li $v0, 4
la $a0, prompt1
syscall
jal loop
#Calculate and print out the result
li $v0, 4
la $a0, prompt3
syscall
jal cal
#Print out the array
li $v0, 4
la $a0, prompt2
syscall
addi $t1, $zero, 0 #clear t1
jal display
li $v0, 10
syscall
loop:
beq $t0, 20, exit
li $v0, 5
syscall
sw $v0, array($t0)
add $t0, $t0, 4 #increase index
j loop
exit:
jr $ra
cal:
la $s5, array
lw $t5, 8($s5)
mul $t3, $t5, 4
li $v0, 1
move $a0, $t3
syscall
jr $ra
display:
beq $t1, 20, exit_display
lw $t6, array($t1)
addi $t1, $t1, 4
#print current number
li $v0, 1
move $a0, $t6
syscall
#print the new line
li $v0, 4
la $a0, newLine
syscall
j display
exit_display:
li $v0, 10
syscall

User ask how many input you want to take and then show their sum in mips

I want to make a program in mips, in which the user will enter the number of inputs he wants to take. Finally the program will print the sum of the inputs.
Here is my code:
.data
myMessage: .asciiz "ENTER numbers you want to sum\n"
value: .asciiz "ENTER Value \n"
sum : .word 0
.text
li $v0, 4
la $a0, myMessage
syscall
li $v0, 5
syscall
move $t0, $v0 #num of time user will enter num
la $t1, 0 #count value first initiallize to 0
see:
bne $t1,$t0,add #checking if count is less than the num of value
li $v0, 1 #printing sum finally
la $a0, ($s2)
add:
li $v0,4
la $a0,value
syscall
li $v0,5
syscall
move $t3,$v0
la $a1, sum #load address of 'bal' in '$a1'
lw $s3, 0($a1) #load sum from '$a1' to '$s2' (initially 0)
add $s3, $s3, $t3 #adding the sum
sw $s2, 0($a1) #load latest sum ('$s2') in .word balance ('$a1')
addi $t1,$t1,1 inc in count
j see
The problem is that the program does not stop after the wished number of inputs and continues to ask for new input.
.data # Data declaration section
instring1: .asciiz "ENTER numbers you want to sum\n"
instring2: .asciiz "Enter value\n"
outstring: .asciiz "Sum: "
.text#
main:
#Print instring1
li $v0, 4 # system call code for printing string = 4
la $a0, instring1 # load address of string to be printed into $a0
syscall # call operating system to perform operation in $v0
# syscall takes its arguments from $a0, $a1,
#Taking n as input
li $v0, 5 # read int
syscall
move $s0, $v0 # the result of the syscall is stored in v0
# we move it to t0 to prevent overwriting
#Creation heap memory
mul $t1, $s0, 4
li $v0, 9
move $a0, $t1
syscall
move $s1, $v0
#Print instring2
li $v0, 4 # system call code for printing string = 4
la $a0, instring2 # load address of string to be printed into $a0
syscall # call operating system to perform operation in $v0
# syscall takes its arguments from $a0, $a1,
li $s2, 0 # $s2 is the index, and loop induction variable
Start_Input:
bge $s2, $s0, End_Input
li $v0, 5 # Read integer values
syscall
mul $t0, $s2, 4 # $t0 is the offset
add $t1, $s1, $t0 # $t1 is the address of desired index
sw $v0, ($t1) # store the value in the array
addi $s2, $s2, 1 # increment the index
j Start_Input
End_Input:
add $t0, $zero, $zero # i is initialized to 0, $t0 = 0
add $s2, $zero, $zero # sum = 0
beq $s0, $zero, print_sum # if number = 0 then goto print_sum
Loop: #stuff
mul $t1, $t0, 4
add $t2, $s1, $t1
lw $t3, ($t2)
add $s2, $s2, $t3
addi $t0, $t0, 1 # i ++
slt $t1, $t0, $s0 # $t1 = 1 if i < n
bne $t1, $zero, Loop # go to Loop if i < n
#Print Sum
print_sum:
li $v0, 4 # system call code for printing string = 4
la $a0, outstring # load address of string to be printed into $a0
syscall # call operating system to perform operation in $v0
# syscall takes its arguments from $a0, $a1,
li $v0 1 # print int
move $a0 $s2
syscall
#Exit Syscall
EXIT:
li $v0 10# exit
syscall
This is working code. Comment provided to understand code.
.data
myMessage:.asciiz "ENTER numbers you want to sum\n"
value:.asciiz "ENTER Value: "
show: .asciiz "\nSum is: "
.text
li $v0,4
la $a0,myMessage
syscall
li $v0,5
syscall
move $t0,$v0 #num of time user will enter num
la $t1, 0 #count value first initiallize to 0
la $t5, 0
see:
bne $t1,$t0,add #checking if count is less than the num of value
li $v0, 4
la $a0, show
syscall #print message "Sum is: "
li $v0, 1
move $a0, $t5
syscall #print the result
j end
add:
li $v0,4
la $a0,value
syscall
li $v0, 5
syscall
add $t5, $t5, $v0
sub $t0, $t0, 1
j see
end:

MIPS - Load integer into array - store address not aligned on word boundary

.data
p1: .asciiz "\nEnter the data for a sorted array: "
p2: .asciiz "\nEnter a value to search for: "
p3: .asciiz " is not found"
p4: .asciiz " is found at "
array: .space 404
.text
main:
la $t0, array # a1 = addr of first int
#Store Array Values
store:
li $v0, 4 # system call code for print_str
la $a0, p1 # address of string to print
syscall # print the first prompt
li $v0, 5 # system call for read_int
syscall # read int to store
move $t1, $v0 # store int
beq $t1, 0, bsearch # once sentinel val hit, go to search
sub $t9, $t0, 4 # set index to the first bit of the last number
j storeVal # store s0 in array
storeVal:
sw $t1, array($t0) # store value in array
addi $t0, $t0, 4 # inc index
j store # continue to add integers
#Binary Search
bsearch:
li $v0, 4 # system call code for print_str
la $a0, p2 # address of string to print
syscall # print the second prompt
li $v0, 5 # system call for read_int
syscall # read int to find
move $a0, $v0 # store int to find
beq $a0, 0, end # once sentinel val hit, go to end prog
la $a2, array # a1 = addr of first int
la $a2, ($t9) # a2 = addr of last int
subu $sp, $sp, 4 # 4 bytes 4 stack
sw $ra, 4($sp) # save return addr
subu $t0, $t9, $s0 # size of array
bnez $t0, searchVal # if not 0, search
move $v0, $a1 # addr of only entry
lw $t0, ($v0) # load entry
beq $a0, $t0, found # if = to int, print found
j notFound # not found
searchVal:
sra $t0, $t0, 3 # comp offset of middle m:
sll $t0, $t0, 2 # t0 = 4(t1/8)
addu $v0, $a1, $t0 # middle m
lw $t0, ($v0) # t0 = m
beq $a0, $t0, found # if = to int, print found
blt $a0, $t0, left # search left
j right # search right
right:
addu $a1, $v0, 4 # search right
jal bsearch
beq $a0, $t0, found # if = to int, print found
j notFound # not found
left:
move $a2, $v0 # search left of m
jal bsearch
beq $a0, $t0, found # if = to int, print found
j notFound # not found
#Print
found:
li $v0, 1 # system call code for print_int
move $a0, $s2 # integer to print (counter
syscall # print it
li $v0, 4 # system call code for print_str
la $a0, p4 # address of string to print
syscall # print the answer part 2
j bsearch # continue to search for more integers
notFound:
li $v0, 1 # system call code for print_int
move $a0, $s2 # integer to print (counter)
syscall # print it
li $v0, 4 # system call code for print_str
la $a0, p3 # address of string to print
syscall # print the answer part 2
j bsearch # continue to search for more integers
#END PROG
end:
li $v0, 10
syscall
I keep getting an error when I attempt to load words into my array, "Error in /../Proj.asm line 58: Runtime exception at 0x00400040: store address not aligned on word boundary 0x200200c2.
57) storeVal:
58) sw $t1, array($t0) # store value in array
59) addi $t0, $t0, 4 # inc index
60) j store # continue to add integers
Line 58 being the sw $t1, array($t0) one. I have tried setting t0 (the line right after .main) the way shown, and setting it to $zero with
addi $t1, $zero, 0
neither of the options will let me set an item into the array, and I cannot find a guide or tutorial to save my life... Also while we're at it, can anyone see if the rest of the code is at least close? Thanks!

Array in Mips Assembly with looping

I am having an issue with my code. I am creating a program that will read in a string, save it into an array and then output the number of times each letter is used in the string. For right now I am having an issue with just the output of the string back to the screen. The string is outputted but the loop never exits, the $t2 value is maybe never set to a value?
.data
intro: .asciiz "Andrew Lofgren, Letter Checker Program"
question: .asciiz "\nPlease enter a string for evaluation: "
alphabet: .ascii "ABCDEFGHIJKLMONOPQRSTUVWXYZ"
results: .space 104
string: .space 1024
.text
main:
jal setup
jal analyze
#jal results
li $v0, 10
syscall
setup:
li $v0, 4 # outputing name and program information
la $a0, intro
syscall
li $v0, 4 # asksing for string input
la $a0, question
syscall
li $v0, 8
la $a0, string
li $a1, 1024
syscall
jr $ra # return
analyze:
la $t0, string # taking string and saving into a tmp
move $t2, $t0 # backup of orignal address
find:
beq $t1, 0, print
addi $t0, $t0, 1
j find
print:
blt $t0, $t2, end #PROBLEM HERE
li $v0, 11
lb $a0, 0($t0)
syscall
addi $t0, $t0, 1
j print
end:
jr $ra
$t0 will never be less than $t2, because $t0 continually increases while $t2 remains the same. To solve this, you need a third register, say $t7, which stores the final index of your string. To calculate the last index, simply add the base address of the string to length which you have defined as 1024. Once $t0 is no longer less than 1024 + string, there are no chars left in the string, and thus we branch to end:. This is done and explained further in the code segment below.
print:
li $t7 , 1024 # Load total byte length of the string
add $t7 , $t7 , $t2 # add it to the base address to get the end
slt $t6 , $t0 , $t7 # check to see if cur index < end
beq $t6 , $0 , end # if we hit the end, branch to end
...
For more information on MIPS instructions, visit this page.

Resources