Basically for a class project/assignment we need to take another persons program in class and correct it for them, if they are good at assembly then your in luck if your person is bad like mine seems to be your screwed. Below is the exact code they posted, I've gone through it a bunch of times and can't even figure out except for where the variables are entered what this person is trying to do or even how to fix it so that it works. If anyone can tell what this person is trying to do, such as how they get from the variable entered part to the actual exponential situation or see a way to fix this problem or basically any help at all I would greatly appreciate it. Thanks in advance.

# Program to:
 # 1 ask the user to type in the value for two variables x and y
 # 2 calculate the exponential function: F(x,y) = x^y
 
 .data 				#variable used follow this line
 promptX: .asciiz "Enter a number for X:"
 promptY: .asciiz "Enter a number for Y:"

.text

main:

li	$v0,	4		# System call code for print string
la	$a0,	promptX 	# Load address of the promptA string
syscall 			# call OS to Print promptX
li 	$v0,	5 		# System call code for read integer
syscall 			# call OS to Read integer into $v0
move 	$a0,	$v0 		# Move the integer into $s0
li	$v0,	4		# System call code for print string
la	$a0,	promptY		# Load address of the promptA string
syscall 			# call OS to Print promptA
li 	$v0,	5 		# System call code for read integer
syscall 			# call OS to Read integer into $v0
move 	$a1,	$v0 		# Move the integer into $s0

#move $a0,$s0
#move $a1,  $s1

jal exponential

move $a0, $v0
li $v0, 1
syscall




exit:
li $v0, 10
syscall

exponential: 
addi $sp, $sp, -4
sw $t0, 4($sp)

move $t0, $zero
li $v0, 1

loop: 
beq $t0, $a1, end
mul $v0, $v0, $a0
addi $v0, $t0, 1
j loop

end:
addi $sp, $sp,  4

jr $ra

Recommended Answers

All 4 Replies

The first problem this person had is that he did not comment his code very well. The second problem is that his comments don't match his code. The third (and most important) problem is that he did not write down what he was trying to do before doing anything.

For example, on lines 16..18 his comments say, basically, "get integer into $s0". However, what he does is stick the integer in $a0. The very next thing he does is clobber $a0 (and $v0) in order to print promptY, so the integer that the user entered is lost forever.

The commentary might better run like this:

.text

# variables
#  $s0 = X
#  $s1 = Y

main:
	# Ask user to "Enter a number for X: "
	li	$v0,	4
	la	$a0,	promptX
	syscall

	# Get X --> $s0
	li	$v0,	5
	syscall
	move	$s0,	$v0

	...

	# $v0 = exponential( $s0, $s1 )
	move	$a0,	$s0	# see note [1]
	move	$a1,	$s1
	jal	exponential

	# print the result
	move	$a0,	$v0
	li	$v0,	1
	syscall

	# terminate the program
	li	$v0,	10
	syscall

[1] Argument passing conventions
The registers $a0..$a3 are typically used as arguments to functions. The exponential() function takes two arguments, so the first argument is $a0 and the second argument is $a1.

We could design the function to take $s0 and $s1 as arguments, then we wouldn't have to move anything around before jal -ing to the function. However, I chose to do it the correct way...

This leads to the next problem: The same thing is missing from the exponential function as the main program: documentation and care taken before writing it to decide exactly what it should look like, what it should do, what registers it will use, and how it will return value. As it has no predefined, explicit definition, it is broken.

We've already decided that the function should look something like this: $v0 = exponential( X = $a0, Y = $a1 ) The first lines of his function look like this:

exponential:
	addi	$sp,	$sp,	-4
	sw	$t0,	4($sp)

Since he is messing with the stack pointer ($sp), you can guess that he is building a stack frame. The first thing to check is to find the end of the function and make sure he restores the stack before returning:

end:
	addi	$sp,	$sp,	4

	jr	$ra

...he does.

Take a moment to think about the purpose of a stack frame: to have a place to store local variables and to preserve the return address (which you need to do if you plan to call another function). The function does not call other functions, but it appears to want to preserve the value of $t0 in a local variable. You'll notice that he forgot to restore the value of $t0 before returning.

In MIPS, the registers $t0..$t7 are "temporary" values: values not expected to be preserved across procedure calls. So there is no actual reason to preserve $t0.

However, that said, let's fix it right, and add the proper cleanup code to the end of the routine --for no other reason than it is an opportunity to play with the stack frame. Let's add some proper commentary also.

#
# Function: exponential
# Arguments:
#   $a0 is X
#   $a1 is Y
# Calculates the value of X raised to the power of Y
# Returns the answer in $v0
# Registers destroyed: none [?]
#
exponential:
	# Preserve $t0 on the stack
	addi	$sp,	$sp,	-4
	sw	$t0,	4($sp)

	...

end:
	# Restore $t0 and the stack
	lw	$t0,	4($sp)
	addi	$sp,	$sp,	4
	jr	$ra

[?] When using assembly, a very useful piece of information is which registers are ruined by a given routine. Since we took the time to save and restore $t0, I'll assume for the moment that no other registers (except, of course, $v0) are clobbered. You'll have to verify that this is true before you are done. If there are registers that are ruined, you'll have to either preserve and restore them on the stack just like we did with $t0, or add them to the list of destroyed registers.

Now that the stack is fixed, and we have pretty good start at documentation, we can move on to the actual body of the procedure. Think about how the exponent is actually calculated.

X^Y is the same as X times itself Y times.

It looks like he is using $t0 as a counter to go from 0 to Y-1, and multiplying X by itself each time through the loop.

The trick now is to look through the function to see if he uses the registers correctly. (He doesn't, so you'll have to straighten it out.)

I'll leave you to think about this a little by yourself. However, here are some hints:

  • there is no need to destroy any other registers.
  • $t0 should be incremented by one each time through the loop.
  • $v0 should be multiplied by $a0 each time through the loop.
  • $zero doesn't exist. Use $0.

Make sure to document how the routine is doing what it does, and give "names" to your registers so that you can say "hmm, register $a1 is Y, so if I am comparing $t0 (my counter) to $a1 (Y) then it looks right." Etc.

Hope this helps and good luck!

Oh yeah, almost forgot. He's mixing SAL and MAL. You can mention that, but there is no need to "fix" it.

Your professor should have given you three sheets, listing SAL, MAL, and TAL instructions, and/or you should have them listed in your textbook. Instructions like move are SAL. Instructions like addi are TAL.

I'm on my way out but saw you responded to this, but once I get back I will read the large post you wrote but according to your second smaller post the professor never said anything about SAL, MAL and TAL, just MIPS which I think doesn't help much. Basically we program in any file editor we want(i use editplus2) and then us pcspim to run the program. Therefore I see what your saying about the no need to fix because hes mixing SAL and MAL, but thats the kind of thing we've been learning the whole semester so yea. Anyway I'll edit this reply once I read the larger post you left.

Okay I took what you said in consideration and got this kids code working and put correct comments for the most part I believe. I'm going to post the code so maybe someone can take a look at it and actually tell me if I did indeed correct all the previous issues. And for the record my program was in a lot better shape than this one, i got jipped :( . But once again thank you so much Duoas for all your help and time.

# Program to:
 # 1 ask the user to type in the value for two variables x and y
 # 2 calculate the exponential function: F(x,y) = x^y
 
 .data 				#variable used follow this line
 promptX: .asciiz "Enter a number for X: "
 promptY: .asciiz "Enter a number for Y: "
 promptR: .asciiz "The result of the exponential funcion: F(x,y) = x^y is "

.text

main:
	li	$v0,	4		# System call code for print string
	la	$a0,	promptX 	# Load address of the promptX string
	syscall 			# call OS to Print promptX
	li 	$v0,	5 		# System call code for read integer
	syscall 			# call OS to Read integer into $v0
	move 	$s0,	$v0 		# Move the integer into $s0
	li	$v0,	4		# System call code for print string
	la	$a0,	promptY		# Load address of the promptY string
	syscall 			# call OS to Print promptY
	li 	$v0,	5 		# System call code for read integer
	syscall 			# call OS to Read integer into $v0
	move 	$s1,	$v0 		# Move the integer into $s1
	move	$a0,	$s0		# Move the integer in $s0 into $a0
	move	$a1,	$s1		# Move the integer in $s1 into $a1
	jal	exponential		# Jum and link to exponential sub routine
	
	# Print out the result
	move	$a0,	$v0
	li	$v0,	1
	syscall 

	# End the Program
	li 	$v0,	10		#System call code to Exit
	syscall				#call OS to Exit the program


exponential: 
	addi	$sp,	$sp,	-4
	sw	$t0,	4($sp)
	move	$t0,	$zero
	li	$v0,	1

loop: 
	beq	$t0,	$a1,	end	# Checks to see if $t0 is equal to $a1 if not
					# it continues, if it is it jumps to end
	mul	$v0,	$v0,	$a0	# Multiplies the value in $a0 by the value in $v0
	addi	$t0,	$t0,	1	# Adds 1 to $t0 and stores it in $t0 because
					# $t0 is the loop counter
	j	loop			# Jumps to the beginning of the loop to start
					# the process over

end:
	#restore $t0 and the stack
	lw	$t0,	4($sp)
	addi	$sp,	$sp,	4
	jr	$ra
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.