Title: CS231 Assignment1
Date: 2017-03-02T00:00:00
Tags: CS231, Assembly
Authors: Henry Brooks

This was a rather complicated problem that mostly tested our ability to think through the procedure clearly and cover edge cases.

This was a rather long assignment to type up however, the instructions made the requirements rather clear. I wasn’t required to do any outside the box thinking here, just put the pieces together correctly.

Lab5.asm

#Henry Brooks
#CS231 Assignment1
.data
array:		.word	1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
str0:		.asciiz	"Please enter the array length: "
goodMsg:	.asciiz	" is a good value in checkNumPositive\n"
badMsg:		.asciiz " is a bad value in checkNumPositive\n"
errorMsg:	.asciiz	"Invalid array length\n"
invalidMsg:	.asciiz	"Invalid array value\n"
space:		.asciiz " "
newline:	.asciiz "\n"

.text
begin:
	la	$a0, str0
	li	$v0, 4
	syscall
	
	jal	readNum		# input passed back in $v1
	add	$s0, $v1, $0	# $s0 = arraySize
	
	add	$a0, $s0, $0	# pass arraySize in $a0 to veriftySize
	jal	verifySize
	add	$t0, $v1, $0	# get 1 or 0 back from verifySize
	
	beq	$t0, $0, begin
	
	add	$a0, $s0, $0	# pass arraySize to createArray in $a0
	jal	createArray
	
	add	$a0, $s0, $0	# pass arraySize to printArray in $a0
	jal	printArray
	
	
	add	$a0, $s0, $0	# pass arraySize to reverseArray in $a0
	jal	reverseArray
	
	
	add	$a0, $s0, $0	# pass arraySize to printArray in $a0
	jal	printArray
	
exit:
	li	$v0, 10
	syscall

#----------- int readNum(), returns and int
readNum:
	li	$v0, 5
	syscall
	add	$v1, $v0, $0	# pass input back in $v1
	jr	$ra

#----------- int verifySize(int arraySize), returns 0 or 1
verifySize:
	add	$t0, $a0, $0	# save passed arg (arraySize) to $t0
	
	li	$t1, 20
	bgt	$t0, $t1, verifySizeBad
	ble	$t0, $0, verifySizeBad
	
	li	$v1, 1			# pass 1 back to main in $v1
	jr	$ra
	
verifySizeBad:
	la	$a0, errorMsg
	li	$v0, 4
	syscall
	
	li	$v1, 0			# pass 0 back to main in $v1
	jr	$ra

#----------- void createArray(int arraySize), returns nothing
createArray:
	add	$s1, $a0, $0	# save passed arg (arraySize) to $s1
	sw	$ra, 0($sp)		# save current $ra to stack
	
	li	$s2, 0			# counter
	la	$s3, array		# create pointer to array[0]
	
createArrayLoop:		# arraySize < counter
	beq	$s1, $s2, createArrayDone	
	
	jal	readNum			# int readNum(), returns int in $v1
	add	$s4, $v1, $0	# save arrayEntry to $s4

#------- int checkNumPositive(arrayEntry), returns 0 or 1	
	add	$a0, $s4, $0	# pass arrayEntry to checkNumPositive
	jal	checkNumPositive
	add	$t0, $v1, $0	# save return value to $t4, either 0 or 1
	
	beq	$t0, $0, createArrayBad

#------- int divisibleBy3(arrayEntry), returns 0 or 1	
	add	$a0, $s4, $0	# pass arrayEntry to divisibleBy3
	jal	divisibleBy3
	add	$t0, $v1, $0	# save return value to $t4, either 0 or 1
	
	beq	$t0, $0, createArrayBad

#------- if both tests pass then save to the array and increment the counters
	sw	$s4, 0($s3)
	
	addi	$s3, $s3, 4	# pointer++
	addi	$s2, $s2, 1	# counter--
	j	createArrayLoop
	
createArrayDone:	
	lw	$ra, 0($sp)	# load old $ra from stack
	jr	$ra

createArrayBad:
	la	$a0, invalidMsg
	li	$v0, 4
	syscall
	
	j	createArrayLoop

#----------- void reverseArray(int arraySize), returns nothing
reverseArray:
	add	$t0, $a0, $0	# save passed arg (arraySize) to $t0
	
	li		$t1, 4		# set $t1 = 4
	mult	$t0, $t1	# length * 4
	mflo	$t1			# set $t1 = length * 4
	
	la	$t2, array	# set pointer to start of the array
	la	$t3, array
	add	$t3, $t3, $t1
	addi	$t3, $t3, -4	# set pointer to end of the array

reverseArraySwap:
	bgt	$t2, $t3, reverseArrayDone
	lw	$t4, 0($t2)
	lw	$t5, 0($t3)
	sw	$t5, 0($t2)
	sw	$t4, 0($t3)
		
	addi	$t2, $t2, 4
	addi	$t3, $t3, -4
	j	reverseArraySwap

reverseArrayDone:
	jr	$ra

#----------- void printArray(int arraySize), returns nothing
printArray:
	add	$t0, $a0, $0	# save passed arg (arraySize) to $t0
	la	$t1, array

printArrayLoop:
	beq	$t0, $0, printArrayDone
	lw	$a0, 0($t1)
	li	$v0, 1
	syscall
	
	li	$v0, 4
	la	$a0, space
	syscall
	
	addi	$t1, $t1, 4
	addi	$t0, $t0, -1
	j	printArrayLoop
	
printArrayDone:
	li	$v0, 4
	la	$a0, newline
	syscall
	jr	$ra

#----------- int divisibleBy3(int arrayEntry) , returns 0 or 1
divisibleBy3:
	add	$t0, $a0, $0	# save passed arg (arrayEntry) to $t0
	
	li	$t1, 3
	div	$t0, $t1
	mfhi	$t3
	
	bne	$t3, $0, divisibleBy3Bad
	
	li	$v1, 1			# pass 1 back to main in $v1
	jr	$ra

divisibleBy3Bad:
	li	$v1, 0			# pass 0 back to main in $v1
	jr	$ra

#----------- int checkNumPositive(int arrayEntry) , return 0 or 1
checkNumPositive:
	add	$t0, $a0, $0	# save passed arg (arrayEntry) to $t0
	
	blt	$t0, $0, checkNumPositiveBad
	
	li	$v1, 1			# pass 1 back to main in $v1
	jr	$ra

checkNumPositiveBad:
	li	$v1, 0			# pass 0 back to main in $v1
	jr	$ra