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!

Recommended Answers

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 …

Jump to Post

All 4 Replies

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?

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.

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! :-)

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.

Be a part of the DaniWeb community

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