Skip to content

Instantly share code, notes, and snippets.

@rsayers
Last active February 17, 2018 20:16
Show Gist options
  • Save rsayers/6c56b1f0ad0cafb25e356abb834ca3d0 to your computer and use it in GitHub Desktop.
Save rsayers/6c56b1f0ad0cafb25e356abb834ca3d0 to your computer and use it in GitHub Desktop.
Project Euler problem 1 example
.data
output_text:
.asciz "%d\n" ;; So we can printf later
.balign 4
.text
.global main
.extern printf ; load external function
;; This program calculates the sum of all positive integers evenly divisible by 3 or 5
;; The python equivalent is:
;; print(sum([i for i in range(1000) if i%3==0 or i%5==0]))
main:
mov r6, #0 ;; r6 will hold the sum of numbers we find
mov r5, #1 ;; r5 will be the var we increment each time
mainloop:
cmp r5, #1000 ;; compare to 1000
beq print_results ;; if it's equal, jump to the print_results section
mov r0, r5 ;; r0 and r1 are the first two arguments sent to functions
mov r1, #3 ;; So with r0==r5, and r1==3, it's like calling mod(VALUE_IN_R5, 3)
bl mod ;; call the mod function
cmp r0, #0 ;; If the return value (r0) is zero, its evenly divisible by 3
beq addval ;; jump to addval if the above is true
;; The next few lines are the same as above, but just check the numbers divisibility with 5
mov r0, r5
mov r1, #5
bl mod
cmp r0, #0
beq addval
;; Increment r5 by 1, and then start our loop over
add r5, r5, #1
b mainloop
;; If we jump here, then add the current value of r5 to r6
addval:
add r6, r6, r5
;; Increment r5 by 1, and then start our loop over
;; This is placed here so it will automatically be reached if we jump to incr
inc_and_loop:
add r5, r5, #1
b mainloop
print_results:
;; Move our final sum to r1 so it can be an argument to printf
mov r1, r6
;; Set our first argument as the value of output_text
ldr r0, =output_text
;; call the printf function
bl printf
;; Set our exit value to 0
mov r0, #0
;; Setup the syscall we want, in this case it's 7, for exit
mov r7, #1
;; perform the syscall
swi #0
mod:
;; First of all, compare the dividend and divisor
cmp r0, r1
;; if they are equal, there's no remainder
beq no_remainder
;; Compare again
cmp r0, r1
;; If the dividend is less than the divisor, exit early and force a remainer of 1
blt less_than
;; Otherwise, subtract the divisor from the dividend
sub r0, r0, r1
;; Compare the values now
cmp r0, r1
;; If the dividend is still greater than or equal to the divisor, start at the top and run again with the new dividend
bge mod
;; Otherwise, r0 now contains the remainder, so return
bx lr
no_remainder:
mov r0, #0
bx lr
less_than:
mov r0, #1
bx lr
.global printf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment