x86-64 Assembly - Sum of multiples of 3 or 5 I'm trying to learn some basic x86 assembly and so I've begun solving Project Euler problems. I was hoping for some critique of my code that, hopefully, includes either the efficiency of the operations or the readability / style of the code itself. I will provide the Makefile for Linux 64 bit.
The purpose of the code is to sum all numbers from [0, 1000) that are divisible by 3 or 5.
The code can be run using make RUN=euler_1.
NB:
I am aware that most compilers replace modulos of known numbers with some combination of mov and shr to avoid the integer division. For example, see this thread.
Makefile
.PHONY: clean

all:    $(RUN).elf
    ./$^

%.elf:  %.o 
    ld $^ -o $@ -lc -e main -dynamic-linker /lib64/ld-linux-x86-64.so.2

%.o:    %.asm
    nasm -f elf64 $^

clean:
    rm -f *.o *.elf

euler_1.asm
extern printf
global main

section .data
fmt: db &quot;%d&quot;, 0x0a, 0

section .text
    
;; main - Calculate the sum of all numbers between [0, 1000) that are divisible
;; by 3 or 5.
;;  sum : R8
main:   
    ; sum = 0
    mov r8, 0   
    ; for i in [0, 1000) {
    mov rcx, 0
for0:   
    ; if i % 3 == 0 or i % 5 == 0 {

    ; i % 3 == 0
    mov rax, rcx
    mov rdx, 0
    mov r9, 3
    div r9
    test rdx, rdx
    jne if01
    ; sum = sum + i
    add r8, rcx
    jmp if0

if01:
    ; i % 5 == 0
    mov rax, rcx
    mov rdx, 0
    mov r9, 5
    div r9
    test rdx, rdx
    jne if0
    ; sum = sum + i
    add r8, rcx
    jmp if0
    ; }
if0:
    inc rcx
    cmp rcx, 1000
    jl  for0
    ; }
    
    ; printf(&quot;%d&quot;, sum)
    lea rdi, [rel fmt]
    mov rsi, r8
    mov rax, 0
    call printf
    
    ; sys_exit(0)
    mov rdi, 0
    mov rax, 60
    syscall
if01 and if0 are not the greatest names.

Instead of reloading r9, use two registers. Let r9 always contain 3, and r10 always contain 5.

Increment r8 in one place.

Running the loop downwards (1000 to 0), rather than upwards, spares an instruction (cmp).

mov rdx, 0 is encoded in 7  bytes. xor rdx, rdx is way shorter.


All that said, consider
main:
    mov r8, 0   
    mov r9, 3
    mov r10, 5

    ; for i in (1000, 0] 
    mov rcx, 999

for0:   
    mov rax, rcx
    xor rdx, rdx
    div r9
    test rdx, rdx
    jeq accumulate

    mov rax, rcx
    xor rdx, rdx
    div r10
    test rdx, rdx
    jne next

accumulate:
    add r8, rcx
next:
    dec rcx
    jne  for0

PS: I hope you know that this problem has a very straightforward arithmetical solution.