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!

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.