Question

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. :(

Was it helpful?

Solution

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top