I am trying to get the sum of 2 numbers but facing difficulties. I did tried to store values in v0 and tried to add them using s0. But it didn't worked out.
#below is an example
.data
int1 : .word 23
int2 : .word 3
result : .word 0
.globl main
.text
main:
lw $t0, int1
lw $t1, int2
add $t2,$t0,$t1
sw $t2, result
li $v0, 1 #these instructions will be used to print
lw $a0, result
syscall
.data
A: .word 2 # this is the block to initialize values
B: .word 4
.text
.globl main
.ent main
main:
lw $t0,A # load value of A in temp register t0
lw $t1,B # load value of B in temp register t1
add $t2,$t0,$t1 # add the value of temp register t0 and t1 then place it in temp register t2
li $v0,10 #
syscall # exit the program
.end main
Related
For our coursework we had to write code in MARS to calculate the memory address of a given coordinate.
.globl main
.data
amountOfRows: .word 16 # The mount of rows of pixels
amountOfColumns: .word 32 # The mount of columns of pixels
promptRows: .asciiz "Please enter the row number:\n"
promptCols: .asciiz "Please enter the column number:\n"
msgShowMemoryAddress: .asciiz "The memory address for the pixel is:\n"
msgErrorValues: .asciiz "The entered value for row/column is invalid, please enter a valid value:\n"
.text
###################################################################################
translate_coordinates:
sw $fp, 0($sp) # push old frame pointer (dynamic link)
move $fp, $sp # frame pointer now points to the top of the stack
subu $sp, $sp, 20 # allocate 16 bytes on the stack
sw $ra, -4($fp) # store the value of the return address
sw $s0, -8($fp) # save locally used registers
sw $s1, -12($fp)
sw $s2, -16($fp)
move $s0, $a0 # $s0 = x coordinate
move $s1, $a1 # $s1 = y coordinate
move $s2, $a2 # $s2 = width for calculations
sll $t3, $s1, 5 # shift y left by 5 which is equal to multiplication of 32
add $t4, $t3, $s0 # (y * 32) + x = index of pixel
sll $t5, $t4, 2 # shift index left by 2 which is equal to multiplication of 4
add $t6, $gp, $t5 # memory address = gp + offset
move $v0, $t6 # place result in return value location
lw $s2, -16($fp) # reset saved register $s2
lw $s1, -12($fp) # reset saved register $s1
lw $s0, -8($fp) # reset saved register $s0
lw $ra, -4($fp) # get return address from frame
move $sp, $fp # get old frame pointer from current fra
lw $fp, ($sp) # restore old frame pointer
jr $ra
###################################################################################
main:
li $v0, 4 # print string
la $a0, promptRows # message to ask the user for the row number
syscall
li $v0, 5 # read integer
syscall # ask the user for a row number
move $t0, $v0
li $v0, 4 # print string
la $a0, promptCols # message to ask the user for the column number
syscall
li $v0, 5 # read integer
syscall # ask the user for a column number
move $t1, $v0
lw $t2, amountOfColumns #load amountOfColumns into $t2
move $a0, $t0 # Put procedure arguments
move $a1, $t1 # Put procedure arguments
move $a2, $t2
jal translate_coordinates # Call procedure
move $t6, $v0 # Get procedure result
move $a0, $t6
li $v0, 1 # syscall code 1 is for print_int
syscall
exit:
li $v0, 10 # syscall to end the program
syscall
I wrote this code to calculate the memory address of a pixel but whenever I run it I get this error:
Error in : invalid program counter value: 0x00000000
We had to use a stackframe for this and I'm quite new to that.
Because I'm quite new to it, it might be that I made some mistakes when it comes to that.
By default, MARS starts running the code at the start of .text, and since in your code the function comes before main, it is running the function without calling it properly.
There are three options:
add j main immediately after .text
use MARS option Settings -> Initialize Program Counter to global main if defined (off by default)
change the order so that main comes immediately after .text
When i run my code i got this
-- program is finished running (dropped off bottom) --
This is my code
.data
array: .space 12 # Reserve 12 bytes of memory for the array
.text
la $t0, array # Load the address of the array into $t0
li $v0, 4 # System call code for printing a string
la $a0, prompt # Load the address of the prompt string
syscall # Print the prompt
.data
prompt: .asciiz "Enter three integers: "
li $v0, 5 # System call code for reading an integer
syscall # Read the first integer
sw $v0, 0($t0) # Store the first integer in the first word of the array
li $v0, 5 # Read the second integer
syscall
sw $v0, 4($t0) # Store the second integer in the second word of the array
li $v0, 5 # Read the third integer
syscall
sw $v0, 8($t0) # Store the third integer in the third word of the array
lw $t1, 0($t0) # Load the first integer into $t1
lw $t2, 4($t0) # Load the second integer into $t2
lw $t3, 8($t0) # Load the third integer into $t3
add $t4, $t1, $t2 # Add the first two integers and store the result in $t4
add $t4, $t4, $t3 # Add the third integer and store the result in $t4
sw $t4, sum # Store the sum in memory
.data
sum: .word 0
li $t5, 3 # Load the value 3 into $t5
div $t4, $t5 # Divide the sum by 3 to get the average
mflo $t4 # Store the result of the division in $t4
sw $t4, avg # Store the average in memory
.data
avg: .word 0
li $t0, 3 # Load the value 3 into $t0
li $t1, 0 # Load the value 0 into $t1
loop:
lw $t2, 0($t0) # Load the next integer from the array into $t2
add $t1, $t1, $t2 # Add the current integer to the sum
addi $t0, $t0, 4 # Move to the next word in the array
bne $
goodday, so currently my code prompts the user to enter a sum. my program then takes these stored values and outputs the sum of them. However, currently my code is not outputting the correct total and i am unsure where the problem lies.
i have attached my code below:
.text
main:
#Prompt
la $a0, prompt
li $v0, 4
syscall
# Get input string
li $v0, 8
la $a0, string_input
li $a1, 1024
move $t0, $a0
syscall
# initialise sum
lb $t2, ($t0) # Initialise the sum as the first value
addi $t2, $t2, -48 # Convert to decimal value
addu $t0, $t0, 1
b loop
loop:
lb $t3, ($t0) # Store the sign
lb $t1, 1($t0) # Store the value
addu $t0, $t0, 2 # increment the counter
beq $t1, 10, end_loop # If reached the end of the string
# Manipulate sign value to 1 if '+'
add $t3, $t3, 4
add $t2, $t2, $t1 # Add the value to the sum
b loop # re-iterate
end_loop:
# Printing the total sum
move $a0, $t2
li $v0, 1
syscall
# Exiting program
li $v0, 10
syscall
.data
string_input: .space 1024
prompt: .asciiz "Enter a sum:\n"
the current output should be 11 but this is what is outputted instead:
Enter a sum:
2+3+6
727
So I have a program that takes an input from the user (integer above 0) and adds up all even numbers below it to achieve a return answer (Ex: input: 7; ans: 2 + 4 + 6 = 12).
The issue with this program is that it's meant to break out of the loop based on if my 'active even variable' ($t1) > the input. Although my program never seems to properly interpret the branch and loops indefinitely until $t1 overflows (I have checked the debugger and know that the program does run the branch line every time). Below is my code:
.data
N: .word 0
Result: .word 0
.text
.globl main
initialize:
li $v0, 5 #getting arg1 from user
syscall
la $t0, N
sw $v0, 0($t0)
li $t1, 2
li $t2, 0
main:
blt $t0, $t1, fin2
fori:
add $t2, $t2, $t1 #t2 += t1
add $t1, $t1, 2 #t1 += 2
slt $t5, $t1, $t0
bne $t5, $zero, fori
fin:
li $v0,1 #prints return value
move $a0, $t2
syscall
li $v0, 10
syscall
fin2:
li $v0,1 #prints return value
move $a0, $zero
syscall
li $v0, 10
syscall
So I don't know if you NEED to be using word storage and such, but really you were just over complicating it in doing so. All you needed was a simple loop which has a counter that increments by 2, checks if it is larger than the initial value, and then add that overall value to the result
.text
.globl main
initialize:
li $v0, 5 # Getting arg1 from user
syscall # System call
move $t0, $v0 # Store the input value in $t0
li $t1, 0 # Initializing the result register
li $t2, 0 # Initializing the addition/counter register
main:
loop:
add $t2, $t2, 2 # Increase the value to be added by 2 (next even value)
bge $t2, $t0, fin # Check if the increment is larger than or equal to the initial input, if so break to finish
add $t1, $t1, $t2 # Increment the result by adding the even value
j loop # jump bak to the top of the loop
fin:
li $v0,1 # let the system know an integer is going to be printed
move $a0, $t1 # Load the result into the $a0 register (the register that prints values)
syscall # System Call
li $v0, 10 # Let the system know the program is going to exit
syscall # System Call
So as you can see $t2 increments by 2 each time. After each increment it is compared to the input value. If the input ($t0) than $t2 then add the value of $t2 to the result ($t1). This way there is an increment counter which is also used to add the necessary even value to the result.
Edit:
Not sure if this is entirely what you meant but I just tossed in some loads and saves, using the s registers as those are the register that are supposed to be used when saving values.
.data
N: .word 0
Result: .word 0
.text
.globl main
initialize:
li $v0, 5 # Getting arg1 from user
syscall # System Call
la $s0, N # Load the address of N into $s0
sw $v0, 0($s0) # Store the input value in 0 index of N
li $t2, 0 # Initializing the addition/counter register
la $s1, Result # Load the address of Result into $s1
main:
sw $t2, 0($s1) # Setting the 0 index of Result to 0
loop:
add $t2, $t2, 2 # Increase the value to be added by 2 (next even value)
lw $t4, 0($s0) # Loading the input value into the $t4 register
bge $t2, $t4, fin # Check if the increment is larger than or equal to the initial input, if so break to finish
lw $t4, 0($s1) # Loading the current result into the $t4 register
add $t4, $t4, $t2 # Increment the result by adding the even value
sw $t4, 0($s1) # Saving the new current result into the $t4 register
j loop # jump bak to the top of the loop
fin:
li $v0,1 # let the system know an integer is going to be printed
lw $a0, 0($s1) # Load the result into the $a0 register (the register that prints values)
syscall # System Call
li $v0, 10 # Let the system know the program is going to exit
syscall # System Call
I am trying to code MIPS to count the number of elements in an array of words that are greater than x and less than y, but the code does not seem to branch properly and I keep getting "count = 9" which is, in this case, the number of elements in my list.
.text
.globl __start
__start: # execution starts here */
la $a0, ans # load str "count ="
li $v0, 4
syscall
la $t0,nums # load array into address
li $t1,0 # setting counter to 0
addi $s0, $zero, 50 # adding constant of 50
addi $s1, $zero, 100 #adding constant of 100
lw $t5,count # loading word "9"
again : lw $t4 ($t0) # load first element of array into t4
bgt $t4,$s0,passif50 #comparing if first element is greater than 50
passif50 : blt $t4,$s1,passif100 #comparing if first element is less than 100
passif100 : add $t1, $t1,1 #incrementing counter by 1
add $t0, $t0,4 #increment current array element pointer
sub $t5,$t5,1 #deincrement "count" word by 1
beqz $t5,done #when "count" word is equal to 0, exit loop
done : move $a0,$t1
li $v0,1
syscall # print the count
li $v0, 10
syscall # end program
.data
nums: .word 55,68,2,60,2000,51,99,1,67
count: .word 9
ans: .asciiz "count = "
endl: .asciiz "\n"