Joseph Mullins

Programmer | Security | Automation

joseph@ropeney.com

Project Euler 1

Back

Project Euler is a collection of Mathematical problems that programmers attempt in their language of choice.

After being reunited with the "operating system" I made in grade 8, I have decided its time to get back in love with x86_64 assembly.
I have chosen to use GNU GAS syntax, so it is compilable with C/C++ functions.

Github

https://github.com/Ropeney/ProjectEulerASM

I will be keeping a git repsository of all the problems so anyone can copy it if they wish to use it!

The first problem involves finding all the natural numbers (whole numbers greater then 0) below 1000, working out if they are multiples of 3 or 5 then adding them together if they are.

Was a good fun problem to start off with for my rusty ASM skills, like always I try to start with a smaller number so when I have to debug its not as long to step through!

# https://projecteuler.net/problem=1
# If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9.
# The sum of these multiples is 23.
#
# Find the sum of all the multiples of 3 or 5 below 1000.
#
# Solution by Joseph Mullins,
# Answer: 233168
#
# Compile with gcc euler_1.s


  .global main

  .text

main:
  mov $1000, %rcx       # rcx will countdown to 0
  xor %rax, %rax        # rax will hold current number
  dec %rcx              # we want everything below this

loop:
  push %rax             # we want to store its current value so its not lost below
  mov $0, %rdx
  mov %rcx, %rax        # Move current counter to rcx
  mov $3, %rbx          # Move 3 into rbx
  div %rbx              # divide it by 3, rdx will hold the remainder

  cmp $0, %rdx          # if rcx was divisible by 5, then rdx will be 0
  je add_to_total       # add this if compare passed

  mov $0, %rdx
  mov %rcx, %rax
  mov $5, %rbx          # check if divisible by 5
  div %rbx              # divide it by 5, rdx will hold the remainder

  cmp $0, %rdx
  je add_to_total       # add this if compare passed

  pop %rax
  dec %rcx              # reduce rcx by 1
  jnz loop              # if not 0 then repeat
  jmp print             # print the output

add_to_total:
  pop %rax              # retrieve what eax was
  add %rcx, %rax        # add current value of rcx to it
  dec %rcx              # reduce rcx by 1
  jmp loop              # rinse and repeat

print:
  mov $format, %rdi     # set first paramter of printf, formatting
  mov %rax, %rsi        # set 2nd paramter (the total value)
  xor %rax, %rax        # printf is varags

  call printf
  ret

format:
  .asciz "%200d\n"

Comments