In: Electrical Engineering
1. Write MIPS assembly code to sum “n” positive integers. For example, n=5, read 5 numbers in memory (“.data” section) and add them together.
2. Write MIPS assembly code to calculate N-factorial. Read n from the memory. (Hint: use “.data” to define the content in a memory location)
Program to find sum of 5 positive integers .data array: .word 23,2,45,67,89 arrend: sum: .asciiz "The sum of the numbers is: " newLine: .asciiz "\n" # Algorithm to sum positive integers # sum = 0 (initial sum = 0) # for i = 0 to 4 # sum = sum + array[i] # registers: # .text main: li $t0,0 # sum = 0 la $t3,array # pointer to current element of array la $t2,arrend # load address of array end j test loop: lw $t4,0($t3) # load array[i] addi $t3,$t3,4 # increment array pointer add $t0,$t0,$t4 # update sum test: blt $t3,$t2,loop # more to do? if yes, loop # print message li $v0,4 la $a0,sumMessage syscall # print sum of 5 numbers li $v0,1 addi $a0,$t0,0 syscall
Program to find Factorial N
.globl main | |
.data | |
msgprompt: .word msgprompt_data | |
msgres1: .word msgres1_data | |
msgres2: .word msgres2_data | |
msgprompt_data: .asciiz "Positive integer: " | |
msgres1_data: .asciiz "The value of factorial(" | |
msgres2_data: .asciiz ") is " | |
# every function call has a stack segment of 12 bytes, or 3 words. | |
# the space is reserved as follows: | |
# 0($sp) is reserved for the initial value given to this call | |
# 4($sp) is the space reserved for a return value | |
# 8($sp) is the space reserved for the return address. | |
# calls may manipulate their parent's data, but parents may not | |
# manipulate their child's data. | |
# i.e: if we have a call A who has a child call B: | |
# B may run: | |
# sw $t0, 16($sp) | |
# which would store data from $t0 into the parent's return value register | |
# A, however, should not(and, in all cases I can think of, cannot) manipulate | |
# any data that belongs to a child call. | |
.text | |
main: | |
# printing the prompt | |
#printf("Positive integer: "); | |
la $t0, msgprompt # load address of msgprompt into $t0 | |
lw $a0, 0($t0) # load data from address in $t0 into $a0 | |
li $v0, 4 # call code for print_string | |
syscall # run the print_string syscall | |
# reading the input int | |
# scanf("%d", &number); | |
li $v0, 5 # call code for read_int | |
syscall # run the read_int syscall | |
move $t0, $v0 # store input in $t0 | |
move $a0, $t0 # move input to argument register $a0 | |
addi $sp, $sp, -12 # move stackpointer up 3 words | |
sw $t0, 0($sp) # store input in top of stack | |
sw $ra, 8($sp) # store counter at bottom of stack | |
jal factorial # call factorial | |
# when we get here, we have the final return value in 4($sp) | |
lw $s0, 4($sp) # load final return val into $s0 | |
# printf("The value of 'factorial(%d)' is: %d\n", | |
la $t1, msgres1 # load msgres1 address into $t1 | |
lw $a0, 0($t1) # load msgres1_data value into $a0 | |
li $v0, 4 # system call for print_string | |
syscall # print value of msgres1_data to screen | |
lw $a0, 0($sp) # load original value into $a0 | |
li $v0, 1 # system call for print_int | |
syscall # print original value to screen | |
la $t2, msgres2 #load msgres2 address into $t1 | |
lw $a0, 0($t2) # load msgres_data value into $a0 | |
li $v0, 4 # system call for print_string | |
syscall # print value of msgres2_data to screen | |
move $a0, $s0 # move final return value from $s0 to $a0 for return | |
li $v0, 1 # system call for print_int | |
syscall # print final return value to screen | |
addi $sp, $sp, 12 # move stack pointer back down where we started | |
# return 0; | |
li $v0, 10 # system call for exit | |
syscall # exit! | |
.text | |
factorial: | |
# base case - still in parent's stack segment | |
lw $t0, 0($sp) # load input from top of stack into register $t0 | |
#if (x == 0) | |
beq $t0, 0, returnOne # if $t0 is equal to 0, branch to returnOne | |
addi $t0, $t0, -1 # subtract 1 from $t0 if not equal to 0 | |
# recursive case - move to this call's stack segment | |
addi $sp, $sp, -12 # move stack pointer up 3 words | |
sw $t0, 0($sp) # store current working number into the top of the stack segment | |
sw $ra, 8($sp) # store counter at bottom of stack segment | |
jal factorial # recursive call | |
# if we get here, then we have the child return value in 4($sp) | |
lw $ra, 8($sp) # load this call's $ra again(we just got back from a jump) | |
lw $t1, 4($sp) # load child's return value into $t1 | |
lw $t2, 12($sp) # load parent's start value into $t2 | |
# return x * factorial(x-1); (not the return statement, but the multiplication) | |
mul $t3, $t1, $t2 # multiply child's return value by parent's working value, store in $t3. | |
sw $t3, 16($sp) # take result(in $t3), store in parent's return value. | |
addi $sp, $sp, 12 # move stackpointer back down for the parent call | |
jr $ra # jump to parent call | |
.text | |
#return 1; | |
returnOne: | |
li $t0, 1 # load 1 into register $t0 | |
sw $t0, 4($sp) # store 1 into the parent's return value register | |
jr $ra # jump to parent call |