1,105,208 Community Members

MIPS Assembly Arithmetic code

Member Avatar
scottd82
Newbie Poster
8 posts since Jan 2012
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

Hi everyone.

I am doing my homework for my computer organization class and I'm running into a small problem. Before I explain what I've done, what I expect to happen and what is happening, I want to assure everyone that I am not looking for an answer to my homework, but a solution to the problem I am having.

First, I am to write a simple arithmetic code for:

D = A^4 + B^6 / 3C - 2B

The code I have written is as follow:

main: #start of main program and load initial values to temporary registers

	li $t0 3	# A=3
	li $t1 6	# B=6
	li $t2 9	# C=9

        # Multiply 3*3*3*3 to get the power of 81

	mul $s1, $t0, $t0	# E = A*A
	mul $s2, $t0, $t0	# E = A*A
	mul $s3, $s1, $s2	# E = E*E

        # Multiply 6*6*6*6*6*6 to get the power of 46656

	mul $s4, $t1, $t1	# F = B*B
	mul $s5, $t1, $t1	# F = B*B
	mul $s6, $t1, $t1	# F = B*B
	mul $s7, $s4, $s5	# F = F*F
	mul $s8, $s6, $s7	# F = F*F

        # Add the products of A and B

	add $t7, $s8, $s3	# G = F*E

        # Multiply C*3 & B*2

	mul $t6, $t2, 3		# H = C*3
	mul $t5, $t1, 2		# I = B*2

        # Subtract the products of H and I

	sub $t4, $t6, $t5	# J = C-B

        # Divide the sum of A and B by the difference of H and I

	div $s0, $t7, $t4	# D = G/J

Now, the problem that happens is when I open my .asm file with this code with PCSpim. PCSpim will stop working and Microsoft forces me to close the program. I don't know where the problem is occurring, but as I was writing the code in the beginning I tested it each time to make sure what I was doing ended up as what I wanted and it was working. So, I just went on to finishing the code then that's where the problem started. Also, I was wondering if someone could explain to me how to use the move pseudoinstruction, as I was told by my professor that this instruction will help limit the amount of machine code lines.

Thank you,
scottd82

Edited: I found the problem. It was on line 36. I had #t7 rather than $t7, which was causing the compiler to crash. However, I still would like some advice on how to use the move pseudo instruction. I would like to shorten my code to make it more efficient. Thanks again!

Member Avatar
rubberman
Senior Poster
3,989 posts since Mar 2010
Reputation Points: 513 [?]
Q&As Helped to Solve: 500 [?]
Skill Endorsements: 87 [?]
 
0
 

Well, the way it is written would be, with scoping parens to mimic the actual operator precidence, D = A^4 + (B^6 / 3C) - 2B

Are you SURE that is what you intend? Or do you mean D = (A^4 + B^6) / (3C - 2B), or something else?

Member Avatar
scottd82
Newbie Poster
8 posts since Jan 2012
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

Well, the way it is written would be, with scoping parens to mimic the actual operator precidence, D = A^4 + (B^6 / 3C) - 2B

Are you SURE that is what you intend? Or do you mean D = (A^4 + B^6) / (3C - 2B), or something else?

You are correct on the latter. It's supposed to be D = (A^4 + B^6) / (3C - 2B). What I'm trying to do now is to make the program more efficient (less machine line codes) and to figure out how to use the move command. I have the program running, just looking for tips on efficiency and the move.

Member Avatar
rubberman
Senior Poster
3,989 posts since Mar 2010
Reputation Points: 513 [?]
Q&As Helped to Solve: 500 [?]
Skill Endorsements: 87 [?]
 
0
 

Well, I have given about as much help as I can, as I don't really know MIPS assembler code in any kind of detail. I've done x86 assembler, but the last time I did any for a production system was in the early 90's when I was writing some TCP/IP driver code for an x86 real-time operating system (QNX). I have tried to stick with C and C++ since then! :-)

Member Avatar
Schol-R-LEA
Nearly a Posting Virtuoso
1,385 posts since Oct 2010
Reputation Points: 635 [?]
Q&As Helped to Solve: 225 [?]
Skill Endorsements: 28 [?]
 
0
 

You may find it worth your while to write a general exponentiation procedure rather than multiplying each time manually. While there is some overhead in a function call, and more in looping to get the result, you need to recall that in a real MIPS CPU (as opposed to SPIM), multiplication takes (IIRC) up to 32 cycles - and if you use the mul pseudo-instruction rather than mult , then you could be waiting the whole 32 cycles to get the results back. If you use mult , and then have other instructions before calling mfhi / mflo for the result, you get around this - again, I am not certain if SPIM accurately reflects this, but it is how real MIPS processors work.

Anyway... as I was saying, an exponentiation function that applies tricks such as using shifts for powers of 2 and successive multiplication can probably be a lot faster than simply multiplying n times in a row.

If nothing else, you can use successive multiplication in your code to eliminate a few multiplications:

# Multiply 3*3*3*3 to get the power of 81

	mul $s1, $t0, $t0	# E` = A*A
	mul $s2, $s1, $s1	# E = E` * E` = A*A*A*A

        # Multiply 6*6*6*6*6*6 to get the power of 46656

	mul $s4, $t1, $t1	# F = B*B
	mul $s5, $s4, $s4	# F = (B*B)*(B*B)
        mul $s6, $s5, $s4       # F = (B*B*B*B)*(B*B)

Later, you can use a shift to replace multiplication by 2:

# Multiply C*3 & B*2

	mul $t6, $t2, 3		# H = C*3
	sll $t5, $t1, 1		# I = B*2

As for the move pseudo-op, what are you uncertain about? It is generally pretty straightforward, being a single-step move from one register to another:

move $t1, $t0

It is equivalent to (and IRRC, assembles into) the following:

or $t1, $zero, $t0

Which has the effect of copying $t0 into $t1.

Question Answered as of 2 Years Ago by rubberman and Schol-R-LEA
You
This question has already been solved: Start a new discussion instead
Post:
Start New Discussion
View similar articles that have also been tagged: