## scottd82 Newbie Poster

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!

## rubberman 1,355

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?

## scottd82

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.

## rubberman 1,355

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

## Schol-R-LEA 1,117

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.