Powers of base 2 between 2 values using array in MIPS

Program requests and reads in exactly one character, which represents an exponent. If the value is acceptable, then the program reads in another value. The program calculates the base 2 power between the user input values, and then stores the calculated values in an array. It then prints the values in the array.

# Assignment 3: Powers of 2 Assembly utilizing Array
# by Hanly De Los Santos
# Copyright ©2009, Hanly De Los Santos. All Rights Reserved.
# http://www.hdelossantos.com
#
# Program requests and reads in exactly one character,
# which represents an exponent. If the value is acceptable, then the
# program reads in another value. The program calculates
# the base 2 power between the user input values, and then
# stores the calculated values in an array. It then prints the
# values in the array.
#
		.text
		.globl __start 

# Load acceptable ascii decimal value for number ranges
# since input is read in as a character.
__start: 	li	$8, 48		# This is the decimal equivalent of 0
		li	$9, 57		# This is the decimal equivalent of 9

# Prompt the user for input.
		la	$11, prompt
		puts	$11

# Grab user input and store value in register 10
		getc	$10
		la	$11, newline	# Create new line
		lb	$17, ($11)
		putc	$17
		add	$15, $10, 0	# Make copy of contents of r10 in r15.
		sub	$15, $15, 48	# Convert char from first input to int.

# Test to determine whether or not the user input value is acceptable.
# If user input is less than 48 and greater than 57, branches to
# exit_donothing, where the user is told the input is wrong.
		bgt	$10, $9, exit_donothing
		blt	$10, $8, exit_donothing
		sub	$10, $10, 48	# After check, convert char to int.

# Prompt user for additional input
		la	$11, prompt2
		puts	$11

# Grab user input and store in r12
		getc	$12
		la	$11, newline	# Create new line
		lb	$17, ($11)
		putc	$17
		add	$18, $10, 0	# Make copy of contents of r12 in r18.
		sub	$18, $18, 48	# Convert char to int.

# Test to determine whether or not the user input value is acceptable.
# If user input is less than 48 and greater than 57, branches to
# exit_donothing, where the user is told the input is wrong.
		bgt	$12, $9, exit_donothing
		blt	$12, $8, exit_donothing
		sub	$12, $12, 48	# After check, convert char to int.

# Determine if the difference between the two user input values is 0
		bnez	$10, neqz
		beqz	$12, special_zero

# Determine difference between 2 values
neqz:		sub	$21, $12, $10	#Store diff of the two values in r21
		bltz	$21, exit_printgtr
		add	$21, $21, 1

# If the value was acceptable, proceed to calculate the power.
		li	$11, 2		# Load multiplier value into $11.
		li	$17, 2		# Initialize 17 to multiplier value

# Check to see if the second usr input is > 1, if it is modify r10 so that
# the calculations can be made properly. This sets r10 = 2. If the second
# input is == 1, then print the results. Must also load 2 into 2nd array
# location here in case the seond input is 1.
		la	$16, powers
		li	$22, 1
		mult	$11, $22
		mflo	$11
		sw	$11, 4($16)
		li	$23, 1
		beq	$23, $12, print_result
		bgt	$10, $23, cont_gtn
		li	$10, 2

# Multiplication loop. While $10 != 0 keep multiplying $17 by 2, and
# decrement $10 by 1 every time this is done. Once $10 == 0, store
# the result.
cont_gtn:	sub	$10, $10, 1	# Since 2^1 has been taken care of
		add	$14, $10, 0
		add	$24, $10, 0
		add	$24, $24, 1

multiply_for:	mult	$17, $11	# Loop to determine the power val
		mflo	$17
		sub	$10, $10, 1
		bnez	$10, multiply_for

# The result is stored in the location of the user input * 4, which would
# give the matching address location on the array. This loops to
# multiply_for while the $10 is != $12.
nextval:	add	$10, $14, 0	# Restores r10 from copy
		mul	$14, $24, 4	# Calculation to determine the
		add	$23, $16, $14	#  location in which to place the
		sw	$17, ($23)	#  resulting power in the array.
		add	$10, $10, 1	# Increment the counters for next
		add	$24, $24, 1	#  iteration.
		add	$14, $10, 0
		li	$17, 2		# restore the multiplier value
		blt	$10, $12, multiply_for
		beq	$10, $12, print_result

# Display the value of the exponential function. This loops through the
# values in the array starting at the first user input until the
# difference between the first and last user input is 0.
print_result:	la	$14, str3
		puts	$14		# Print out "2^"
		li	$v0, 1
		move	$a0, $15
		syscall			# Print out value of user input.
		la	$16, str4
		puts	$16		# Print out '='
		li	$v0, 1
		la	$20, powers	# Calculation to determine the
		mul	$19, $15, 4	#  location of the power value.
		add	$23, $20, $19
		lw	$17, ($23)
		move	$a0, $17
		syscall			# Print out result.
		la	$13, newline	# Create new line
		lb	$12, ($13)
		putc	$12
		sub	$21, $21, 1
		add	$15, $15, 1
		bnez	$21, print_result
		b	endofline

# Print out the result for 2 to the power of 0 if teh two user
# inputs are 0 (special case).
special_zero:	la	$14, str3
		puts	$14		# Print out "2^"
		li	$v0, 1
		move	$a0, $15
		syscall			# Print out value of user input.
		la	$16, str4
		puts	$16		# Print out '='
		li	$v0, 1
		la	$20, powers
		lw	$17, ($20)	# Print first value of array.
		move	$a0, $17
		syscall
		la	$13, newline	# Create new line
		lb	$12, ($13)
		putc	$12
		b	endofline

# If second input is less than or not equal to first input, print mbgtrthan.
exit_printgtr:	la	$13, mbgtrthan
		puts	$13

# If the input is not appropriate, print str2 and exit.
exit_donothing:	la	$13, str2
		puts	$13
		b	endofline

# This is the exit statement.
endofline:	done		# END OF PROGRAM

# Define strings which will be used throughout program
		.data
prompt:		.asciiz "Enter a digit '0'-'9': "
prompt2:	.asciiz "Enter another digit '0'-'9': "
mbgtrthan:	.asciiz "Second digit must be greater than or equal to the first digit.\n"
str2:		.asciiz "Bad user input.  Quitting.\n"
str3:		.asciiz "2^"
str4:		.asciiz " = "
newline:  	.byte  '\n'
		.align 4
powers:		.word	1:10		# Create a 10-element int array.

Leave a Reply