Last active
February 17, 2018 20:16
-
-
Save rsayers/6c56b1f0ad0cafb25e356abb834ca3d0 to your computer and use it in GitHub Desktop.
Project Euler problem 1 example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.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