Looking at the code, it is not solving Project Euler #1, which asks for
S = 3 + 5 + 6 + 9 + ... + 995 + 996 + 999
Your code is solving ...
S = + 0 + 3 + 6 + 9 + ... + 999 + 0 + 5 + 10 + ... + 995 - 0 - 15 - 30 - ... - 990
... which looks like steps for a completely different problem. In short, you've done some work to transform the algorithm from something that needs to test if a value is a multiple of 3 or 5, to a different algorithm which simply sums multiples. You could do more work and simplify into an algebraic formula with no looping at all (although you would need to use DIV).
If you were asked a slightly different problem, the extra 0's being used in your loops could become an issue. For instance, if asked for the product instead of the sum, your formulation would have your first step multiplying by 0! You could easily skip the zeros using
mov r1, #3,
mov r1, #5 and
mov r1, #15 instead of the three
mov r1, #0 statements.
You've got a hard coded limit. The problem indicates that the value
23 would be returned if you use a limit of
10, and then asks for the value returned for a limit of
1000. Would you write completely different code if you wanted to evaluate with the first limit? Probably not.
Instead, write the code as a function. The input parameter
limit would be placed in
r0 before calling the function (
bl euler1). Move it into
r2 inside the function, and then replace occurrences of
cmp r1, #lim with
cmp r1, r2. The result is left in
r0 for when the function returns. You're now using additional registers (
r2 as well as the link register), but the function can validate the problem's test data before computing the actual answer:
; Test case to verify implementation
mov r0, #10
cmp r0, #23 ; Did it work?
; Solve actual Project Euler 1 problem
mov r0, #lim
; r0 should have actual answer here.