views:

51

answers:

1

I'm rewriting my answer(s) to Project Euler questions in MIPS assembly, and I can't get this one to output the correct answer. I've gone over the code for the past hour, and I can't figure out what's wrong with my approach (as I am getting 33165 when the answer is a cool 200,00+ higher than that), so I figure the problem must be my shakiness with the syntax. Is there something foolish I am doing here, like using a reserved register?

## p1.asm
## 
## Andrew Levenson, 2010
## Project Euler, Problem 1
## In MIPS Assembly for SPIM

## Calculate the sum, s, 
## of all natural numbers, n,
## Such that n < 1000.
        .text
        .globl  main

main:
        ori     $8, $0, 0x0     # Init sum s in $8 to 0
        ori     $9, $0, 0x0     # Init variable number n in $9 to 0
        ori     $10, $0, 0x3    
        ori     $11, $0, 0x5
        la      $14, lim         


loop:
retry:
        addiu   $9, $9, 0x1     # Increment n by 1

    # Is n less than 1000?
        sltiu   $15, $9, 1000   # if n >= 1000 then jump to print
        beq     $15, $0, print  # if $15 == 0 

        sll     $0, $0, $0      # no op


    # Is n a multiple of three or five?
        div     $9, $10         # n / 3
        mflo    $12             # $12 = floor( n / 3 ) 
        mfhi    $13             # $13 = n mod 3 

        bne     $13, $0, retry  # if n mod 3 != 0 then retry
        sll     $0, $0, $0      # no op
        beq     $13, $0, sum    # else, print
        sll     $0, $0, $0      # no op

        div     $9, $11         # n / 5
        mflo    $12             # $12 = floor( n / 5 ) 
        mfhi    $13             # $13 = n mod 5 

        bne     $13, $0, retry  # if n mod 5 != 0 then retry
        sll     $0, $0, $0      # no op

    # If we've made it this far, n is good!
sum:
        addu    $8, $8, $9      # s = s + n

        j       loop            # jump to loop
        sll     $0, $0, $0      # no op


print:
        li      $v0, 1          # system call #1 - print int
        move    $a0, $8
        syscall                 # execute

exit:   
        li      $v0, 0xA        # system call #10 - exit
        syscall 



## End of Program

## Variable declarations    
                .data
lim:            .word   1000    # loop bound

EDIT: Code adjusted since being posted. Made fixes suggested, but it still yields an answer off by approximately 100,000. :(

+1  A: 

By incrementing $9 by 3 at each loop, you're missing many multiples of 5, starting with 5...

UPDATE: by branching when $9 is not divisible by 3, and then by 5, you're only keeping the multiples of 3 and 5.

UPDATE: You must remove the following line:

bne     $13, $0, retry  # if n mod 3 != 0 then retry
pascal
Wow... I can't believe I missed that, thanks. Unfortunately, it still doesn't yield the correct answer.
Andrew
I made the fixes you pointed out, and made another change or two (I think? It's pretty late here), but now it is yielding 166,833 which is still off by about 100K. The code is updated one last time for tonight, but I think I need to drag myself into bed. Thanks for looking for my rookie mistakes. :)
Andrew