7
\$\begingroup\$

I just started learning MIPS assembly at my university and I would like some feedback on this code. The program is Project Euler Problem #1, finding the sum of multiples of 3 or 5 less than 1000. It works but I am interested to hear what I could do to improve it (best practice, efficiency, etc). I found x86 solutions to this problem but it seems very different than MIPS.

$
# Testing.asm
    .text 

main:           

    li  $t0, 1000       # number of iterations
    li  $t1, 3          # starting number
    li  $t2, 0          # sum of multiples of 3 or 5
    li  $t6, 3          # constant of 3
    li  $t7, 5          # constant of 5

    loop:
    beq $t1, $t0, end   # end loop if iterator and number of iterations is equal
    div $t1, $t6        # divide iterator by 3
    mfhi    $t3         # $t3 is remainder of iterator divided by 3
    beq $t3, 0, equal       # if remainder is 0, go to equal label
    div $t1, $t7        # divide iterator by 5
    mfhi    $t3         # move remainder into $t3
    beq $t3, 0, equal       # go to equal if remainder is 0
    add $t1, $t1, 1     # increment iterator by 1
    j   loop

    equal:
    add $t2, $t2, $t1       # increment $t2 by iterator
    add $t1, $t1, 1     # increment iterator by 1
    j   loop            # jump back to loop


    end:
    move    $a0, $t2        # load answer into $a0
    li  $v0, 1          # set syscall to print_int
    syscall

    li  $v0, 10         # terminate program
    syscall
\$\endgroup\$

2 Answers 2

5
\$\begingroup\$

Your code is very clean and simplistic, which is a good thing. There is just one glaring problem that I see.


div

As you may already know, the div instruction is very slow instruction. I don't know precisely how slow, but on the x86 systems, the instruction has a latency of about 70.

A better solution would be to treat two registers as counters for the numbers 3 and 5. Here is what I mean by that:

  1. Load register A with 3
  2. Load register B with 5
  3. Subtract 1 from A
  4. Subtract 1 from B
  5. If A == 0, increment the total by the iterator. Load A with 3 and go to step 3.
  6. If B == 0, increment the total by the iterator. Load B with 5 and go to step 5.

By replacing these steps with the div instruction, your code will run significantly faster.


If you would like me to show you how your code would look with the above change, let me know in a comment.

\$\endgroup\$
1
  • \$\begingroup\$ I did not know that div was so inefficient, thank you. I had to read that a few times before I understood what was going on but that is really clever. I'll be sure to remember that in the future. \$\endgroup\$
    – coustyx
    Commented Aug 27, 2015 at 0:05
1
\$\begingroup\$
  • Consider adding a blank line under each label name so that they stand out better. It's not quite enough to see that each one is associated with a separated block of code.

  • Consider adding a comment before each label that describes their purpose. These comments could also include information on register usage. The individual comments are still good to keep, but try not to keep any that are too obvious. I believe all of yours are fine, but I can't say much on that as I'm not familiar enough with MIPS in particular.

\$\endgroup\$
3
  • \$\begingroup\$ MIPS gives me an error if I use immediates for 3 and 5 for the div operation, so "div $t1, 5" would not assemble. As far as I know I have to load them into a register as a constant for it to work. I will follow the rest of the advice though, thank you for the feedback. \$\endgroup\$
    – coustyx
    Commented Aug 27, 2015 at 0:59
  • \$\begingroup\$ @coustyx: Thanks for the correction. I can still remove that part. \$\endgroup\$
    – Jamal
    Commented Aug 27, 2015 at 1:01
  • \$\begingroup\$ A better way to make labels stand out is to indent them to column zero, instead of the same amount as instructions. Some people even put a label on the same line as an instruction, but that's messy unless you indent insns really far and/or always have very short labels. \$\endgroup\$ Commented Sep 18, 2015 at 18:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.