Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #anpoulos
- ###########################################################
- # Program Description
- #
- # CS315 Lab 7 assignment
- #
- # Use create_array to create two arrays
- # Use inner_product to calculate the inner product of the arrays
- #
- ###########################################################
- # Register Usage
- # $t0
- # $t1
- # $t2
- # $t3
- # $t4
- # $t5
- # $t6
- # $t7
- # $t8
- # $t9
- #
- # TODO:
- # Add register descriptions
- #
- ###########################################################
- .data
- intro_p: .asciiz "CS315 Lab 7 - Passing arguments on stack\n\n"
- arrayALen_p: .asciiz "Enter a length for array A: "
- createA_p: .asciiz "\nCreating array A...\n"
- arrayBLen_p: .asciiz "Enter a length for array B: "
- createB_p: .asciiz "\nCreating array B...\n"
- innerProd_p: .asciiz "\nInner product: "
- baseA: .word 0 # Base address for array A
- lengthA: .word 0 # Length of array A
- baseB: .word 0 # Base address for array B
- lengthB: .word 0 # Length for array B
- ###########################################################
- .text
- main:
- # printString(intro_p)
- li $v0, 4
- la $a0, intro_p
- syscall
- # Get and store length for array A
- li $v0, 4
- la $a0, arrayALen_p
- syscall # Print 'enter length'
- li $v0, 5
- syscall # Read length
- la $t0, lengthA # Load lengthA address
- sw $v0, 0($t0) # Store length at lengthA address
- # Get and store length for array B
- li $v0, 4
- la $a0, arrayBLen_p
- syscall # Print 'enter length'
- li $v0, 5
- syscall # Read length
- la $t0, lengthB
- sw $v0, 0($t0) # Store length
- # Create array A
- li $v0, 4
- la $a0, createA_p
- syscall # Print 'creating'
- # If we needed to back up registers, this is where we
- # would do it (i.e. right here, before $ra)
- addiu $sp, $sp, -4 # Allocate memory for $ra
- sw $ra, 0($sp) # Store $ra
- addiu $sp, $sp, -8 # Allocate memory for arguments
- la $t0, lengthA # Load address of lengthA
- lw $t0, 0($t0) # Read the value from lengthA...
- sw $t0, 0($sp) # ...then write that value to the stack
- jal create_array # Call create_array
- lw $t0, 4($sp) # Load base address from stack
- la $t1, baseA # Load address of baseA
- sw $t0, 0($t1) # Store base address at baseA
- addiu $sp, $sp, 8 # Deallocate argument memory
- lw $ra, 0($sp) # Restore $ra
- addiu $sp, $sp, 4 # Deallocate memory for $ra
- # If we backed up any registers, this is where we
- # would restore them and deallocate the stack memory
- # used by the backups
- # Create array B
- li $v0, 4
- la $a0, createB_p
- syscall # Print 'creating'
- addiu $sp, $sp, -4 # Allocate memory for $ra
- sw $ra, 0($sp) # Store $ra
- addiu $sp, $sp, -8 # Allocate memory for arguments
- la $t0, lengthB # Load address of lengthB
- lw $t0, 0($t0) # Read the value from lengthB...
- sw $t0, 0($sp) # ...then write that value to the stack
- jal create_array # Call create_array
- lw $t0, 4($sp) # Load base address from stack
- la $t1, baseB # Load address of baseB
- sw $t0, 0($t1) # Store base address at baseB
- addiu $sp, $sp, 8 # Deallocate argument memory
- lw $ra, 0($sp) # Restore $ra
- addiu $sp, $sp, 4 # Deallocate memory for $ra
- # If we backed up any registers, this is where we
- # Load bases and lengths from their variables into $t registers
- la $t0, baseA
- lw $t0, 0($t0) # t0 <-- mem[baseA]
- la $t1, lengthA
- lw $t1, 0($t1) # t1 <-- mem[lengthA]
- la $t2, baseB
- lw $t2, 0($t2) # t2 <-- mem[baseB]
- la $t3, lengthB
- lw $t3, 0($t3) # t3 <-- mem[lengthB]
- # TODO: Use inner_product to calculate the inner product
- # of arrays A and B
- addiu $sp, $sp, -24 #reserving values on stack
- sw $t0, 0($sp) #address of dyn array A
- sw $t1, 4($sp) #lengthA
- sw $t2, 8($sp) #address of dyn array B
- sw $t3, 12($sp) #lengthB
- sw $ra, 16($sp) #ra
- jal inner_product
- lw $t0, 20($sp) #loads sum of inner products to t0
- lw $ra, 16($sp) #loads ra
- addiu $sp, $sp, 24 #deallocates stack
- la $a0, innerProd_p
- li $v0, 4 #prints innerprod string
- syscall
- move $a0, $t0 #loads sum of inner products to a0
- li $v0, 1
- syscall
- # TODO: Print inner product of A and B
- mainEnd:
- li $v0, 10
- syscall # Halt
- ###########################################################
- ###########################################################
- # Subprogram Description
- #
- # Calculates the inner product of two arrays
- #
- # Inner product:
- # For arrays A and B of equal length n, the inner product
- # is calculated as:
- # A[0]*B[0] + A[1]*B[1] + A[2]*B[2] + ... + A[n-1]*B[n-1]
- #
- # http://en.wikipedia.org/wiki/Dot_product
- #
- # If array lengths do not match or either length is less
- # than or equal to 0, print an error and return 0
- #
- ###########################################################
- # Arguments In and Out of subprogram
- #
- # $a0
- # $a1
- # $a2
- # $a3
- # $v0
- # $v1
- # $sp+0 Base address of array A (IN)
- # $sp+4 Length of array A (IN)
- # $sp+8 Base address of array B (IN)
- # $sp+12 Length of array B (IN)
- # $sp+16 RA from main (IN)
- # $sp+20 Sum of inner products (OUT)
- ###########################################################
- # Register Usage
- # $t0 - address A
- # $t1 - length A
- # $t2 - address B
- # $t3 - length B/counter
- # $t4 - sum of inner
- # $t5 - word from A
- # $t6 - word from B
- # $t7 -
- # $t8 - sum of word A and word B
- # $t9 -
- ###########################################################
- .data
- lengthError_p: .asciiz "\nERROR: Invalid array length(s)\n"
- ###########################################################
- .text
- inner_product:
- # TODO: Write this subprogram
- # Note: This subprogram may require the use of
- # many $t registers
- lw $t0, 0($sp) #address array A
- lw $t1, 4($sp) #length array A
- lw $t2, 8($sp) #address array B
- lw $t3, 12($sp) #length array B
- li $t4, 0 #sum of inners
- beq $t1, $t3, continue #if they are equal, ingore the error
- error:
- la $a0, lengthError_p
- li $v0, 4 #prints error if lengths are not equal and exits
- syscall
- b ipEnd
- continue:
- li $t3, 0 #counter
- addiu $t0, -4 #address A -4
- addiu $t2, -4 #address B -4
- loop:
- beq $t3, $t1, ipEnd
- addiu $t0, $t0, 4 #increment address A by 4
- addiu $t2, $t2, 4 #increment address B by 4
- lw $t5, 0($t0) #loads word from array A at index i
- lw $t6, 0($t2) #loads word from array B at index i
- add $t8, $t5, $t6 #adds words together, stores in t8
- add $t4, $t8, $t4 #t4 += t8
- addiu $t3, 1 #t3 += 1
- b loop
- ipEnd:
- sw $t4, 20($sp) #sum of inners
- jr $ra # Return
- ###########################################################
- ###########################################################
- # Subprogram Description
- #
- # Dynamically allocate array of words
- # Use read_array to fill entire array
- #
- ###########################################################
- # Arguments In and Out of subprogram
- #
- # $a0
- # $a1
- # $a2
- # $a3
- # $v0
- # $v1
- # $sp+0 Array length (IN)
- # $sp+4 Base address (OUT)
- # $sp+8
- # $sp+12
- ###########################################################
- # Register Usage
- # $t0 Length
- # $t1 4
- # $t2 dynamic array address
- # $t3
- # $t4
- # $t5
- # $t6
- # $t7
- # $t8
- # $t9
- ###########################################################
- .data
- ###########################################################
- .text
- create_array:
- lw $t0, 0($sp) # Load length
- sw $0, 4($sp) # Initialize address to 0
- blez $t0, caEnd # End if length <= 0
- # TODO: Finish this subprogram
- # Allocate array
- li $t1, 4 #loads t1 with 4, offset for each word created in dynamic array
- mult $t0, $t1 #generates number of bytes required for dyn array
- mflo $a0 #numb of bytes
- li $v0, 9
- syscall #reserves numb of bytes in a0, stores address in v0
- sw $v0, 4($sp) #stores array address on stack
- addiu $sp, $sp, -4 #reserve
- sw $ra, 0($sp) #stores ra on stack
- jal read_array
- # Call read_array to fill the array
- # Return the base address on the stack
- caEnd:
- lw $ra, 0($sp) #loads ra from stack
- addiu $sp, $sp, 4 #deallocates
- jr $ra # Return
- ###########################################################
- ###########################################################
- # Subprogram Description
- #
- # Print an array
- #
- ###########################################################
- # Arguments In and Out of subprogram
- #
- # $a0
- # $a1
- # $a2
- # $a3
- # $v0
- # $v1
- # $sp+0 Base address (IN)
- # $sp+4 Length (IN)
- # $sp+8
- # $sp+12
- ###########################################################
- # Register Usage
- # $t0 Array address
- # $t1 Loop countdown
- # $t2
- # $t3
- # $t4
- # $t5
- # $t6
- # $t7
- # $t8
- # $t9
- ###########################################################
- .data
- ###########################################################
- .text
- print_array:
- lw $t0, 0($sp) # t0 <-- base address
- lw $t1, 4($sp) # t1 <-- length
- paWhile:
- blez $t1, paEndWhile # while(t1 > 0)
- lw $a0, 0($t0) # $a0 <-- mem(t0 + 0)
- li $v0, 1
- syscall # printInt(a0)
- li $a0, 0x20 # 0x20 == ASCII space
- li $v0, 11 # System call 11, print character
- syscall # printChar(' ')
- addiu $t0, $t0, 4 # t0 <-- t0 + 4
- addiu $t1, $t1, -1 # t0 <-- t0 - 1
- b paWhile # Loop
- paEndWhile:
- paEnd:
- jr $ra # Return
- ###########################################################
- ###########################################################
- # Subprogram Description
- #
- # Read values into an array
- # Fills entire array
- #
- ###########################################################
- # Arguments In and Out of subprogram
- #
- # $a0
- # $a1
- # $a2
- # $a3
- # $v0
- # $v1
- # $sp+0 Base address (IN)
- # $sp+4 Length (IN)
- # $sp+8
- # $sp+12
- ###########################################################
- # Register Usage
- # $t0 Array address
- # $t1 Loop countdown
- # $t2
- # $t3
- # $t4
- # $t5
- # $t6
- # $t7
- # $t8
- # $t9
- ###########################################################
- .data
- enterValue_p: .asciiz "Enter an integer: "
- ###########################################################
- .text
- read_array:
- lw $t0, 8($sp) # t0 <-- base address
- lw $t1, 4($sp) # t1 <-- length
- raWhile:
- blez $t1, raEndWhile # while(t1 > 0)
- li $v0, 4
- la $a0, enterValue_p
- syscall # Print 'enter value'
- li $v0, 5
- syscall # Read integer
- sw $v0, 0($t0) # Store entry
- addiu $t0, $t0, 4 # Increment address
- addiu $t1, $t1, -1 # Decrement counter
- b raWhile # Loop
- raEndWhile:
- raEnd:
- jr $ra # Return
- ###########################################################
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement