# This program includes a variety of procedures for managing # 2-dimensional vectors (point coordinates). # A v2 object is two words long. The first word is the x-coordinate, # the second word is the y-coordinate. .data # The following entries go in the data segment strName: .asciiz "Author: Doug Johnson\n" strTaskA: .asciiz "\nVector Addition\n\n" strTaskB: .asciiz "\nVector Equality\n\n" strComma: .asciiz "," strSeparator: .asciiz " -> " strNewline: .asciiz "\n" coords: .word 0,0,10,0,10,10,0,10 endtag: # must be the address after the array origin: # the point (0,0) .word 0,0 delta: # offset amount added to each original vector .word 0,0 result: # result of adding coord vector plus delta .word 0,0 # stack frame layout # 28($sp) unused # 24($sp) $ra # 20($sp) $s1 # 16($sp) $s0 # 12($sp) reserved for callee: $a3 save space # 8($sp) reserved for callee: $a2 save space # 4($sp) reserved for callee: $a1 save space # 0($sp) reserved for callee: $a0 save space .text # The following entries go in the text (program code) segment main: subu $sp,$sp,32 # create stack frame sw $ra,24($sp) # save return address sw $s1,20($sp) # save $s1 sw $s0,16($sp) # save $s0 # print the name of the program's author la $a0,strName # load name string address li $v0,4 # load print_string code syscall # print # print the name of the first task la $a0,strTaskA # load task label address li $v0,4 # load print_string code syscall # print # set the delta vector to (dx,dy) la $a0,delta # delta vector address li $a1,3 # dx = 3 li $a2,7 # dy = 7 jal v2Set # set delta # look at each vector in the array # print the vector, add delta to the vector, print the result vector la $s0,coords # $s0 = next = address(coords) la $s1,endtag # $s1 = endtag = address(endtag) beq $s0,$s1,mainExit # if array length is zero, then quit mainLoopA: move $a0,$s0 # address of next vector jal v2Print # print the vector la $a0,strSeparator # separator string address li $v0,4 # print_string code syscall # print move $a0,$s0 # reload source vector address la $a1,delta # load address of offset amount la $a2,result # load address of resulting vector jal v2Add # add the vectors la $a0,result # address of result vector jal v2Print # print the result vector la $a0,strNewline # newline address li $v0,4 # print_string code syscall # print addi $s0,8 # point to next vector in array bne $s0,$s1,mainLoopA # loop if more data in array # print the name of the second task la $a0,strTaskB # load task label address li $v0,4 # load print_string code syscall # print # look at each vector in the array # if the vector is not the origin, print the vector la $s0,coords # $s0 = next = address(coords) la $s1,endtag # $s1 = endtag = address(endtag) mainLoopB: move $a0,$s0 # address of current vector la $a1,origin # address of origin vector jal v2Equal # check for equal bnez $v0,mainIfSkip # skip if vector is equal to origin move $a0,$s0 # address of vector jal v2Print # print the vector la $a0,strNewline # newline address li $v0,4 # print_string code syscall # print mainIfSkip: addi $s0,8 # point to next vector in array bne $s0,$s1,mainLoopB # loop if more data in array mainExit: lw $ra,24($sp) # restore return address lw $s1,20($sp) # restore $s1 lw $s0,16($sp) # restore $s0 addu $sp,$sp,32 # release stack frame jr $ra # return #-------------------------------------------------------------------- # v2Set(int *vec,x,y) # Set the contents of a vector in memory # $a0 - vec - address of a 2-element word vector # $a1 - x - value to put in the first element of vec # $a2 - y - value to put in the second element of vec v2Set: sw $a1,0($a0) # store the first value in vec[0] sw $a2,4($a0) # store the second value in vec[1] jr $ra #-------------------------------------------------------------------- # v2Print(int *vec) # Print the contents of a vector in memory # $a0 - vec - address of the 2-element word vector to print v2Print: move $t0,$a0 # remember address of vec lw $a0,0($t0) # load the x coordinate li $v0,1 # load print_integer code syscall # print la $a0,strComma # load address of the string to print li $v0,4 # load print_string code syscall # print lw $a0,4($t0) # load the y coordinate li $v0,1 # load print_integer code syscall # print jr $ra #-------------------------------------------------------------------- # v2Add(int *a,int *b,int *c) # Add the contents of two vectors and store the result in # a third vector # $a0 - a - address of one vector operand # $a1 - b - address of another vector operand # $a2 - c - address of the vector in which to store the sum a+b. v2Add: lw $t0,0($a0) # get a[0] lw $t1,0($a1) # get b[0] add $t2,$t0,$t1 # add sw $t2,0($a2) # store result in c[0] lw $t0,4($a0) # get a[1] lw $t1,4($a1) # get b[1] add $t2,$t0,$t1 # add sw $t2,4($a2) # store result in c[1] jr $ra #-------------------------------------------------------------------- # int v2Equal(int *a,int *b) # Compare the contents of two vectors # Return 1 if equal, 0 if not equal # $a0 - a - address of one 2-element word vector # $a1 - b - address of another 2-element word vector # $v0 - 1 (true) if equal, 0 (false) if not equal v2Equal: move $v0,$zero # return false by default lw $t0,0($a0) # get a[0] lw $t1,0($a1) # get b[0] bne $t0,$t1,v2EqualReturn lw $t0,4($a0) # get a[1] lw $t1,4($a1) # get b[1] bne $t0,$t1,v2EqualReturn li $v0,1 # return true v2EqualReturn: jr $ra