hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/aoc-2025
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-09-06 00:40:37 +0200
committerhachem <im@hachem.wtf>2026-09-06 00:40:37 +0200
commit78c4d3d06d8e863cfe2489281ccfe206544cbd7f (patch)
tree8635d19a9f52210f03edf87cb77365a981cc7029 /aoc-2025
parent42b942404eef0c2af3fc1ec88414793cc6b940a3 (diff)
fix: add utilities
Diffstat (limited to 'aoc-2025')
-rw-r--r--aoc-2025/day1.asm96
-rw-r--r--aoc-2025/day10.asm97
-rw-r--r--aoc-2025/day11.asm95
-rw-r--r--aoc-2025/day12.asm120
-rw-r--r--aoc-2025/day2.asm94
-rw-r--r--aoc-2025/day3.asm69
-rw-r--r--aoc-2025/day4.asm97
-rw-r--r--aoc-2025/day5.asm116
-rw-r--r--aoc-2025/day6.asm96
-rw-r--r--aoc-2025/day7.asm96
-rw-r--r--aoc-2025/day8.asm115
-rw-r--r--aoc-2025/day9.asm114
-rw-r--r--aoc-2025/utils/io.asm107
-rw-r--r--aoc-2025/utils/parse.asm22
14 files changed, 182 insertions, 1152 deletions
diff --git a/aoc-2025/day1.asm b/aoc-2025/day1.asm
index f130675..928e7a5 100644
--- a/aoc-2025/day1.asm
+++ b/aoc-2025/day1.asm
@@ -5,18 +5,10 @@ default rel
global _start
-%define SYS_EXIT 60
-%define SYS_READ 0
-%define SYS_WRITE 1
-%define SYS_OPEN 2
-%define SYS_CLOSE 3
-
-%define O_RDONLY 0
-%define STDOUT 1
+%include "utils/io.asm"
section .data
input_path db "input/day1.txt", 0
- newline db 10
label1 db "Password 1: ", 0
label2 db "Password 2: ", 0
@@ -30,7 +22,6 @@ section .data
section .bss
buffer resb 4096
line_buffer resb 256
- number_buffer resb 16
line_len resd 1
section .text
@@ -128,26 +119,14 @@ print_results:
mov rcx, label1
call print_string
mov eax, [password1]
- call print_int
-
- ; newline
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, newline
- mov rdx, 1
- syscall
+ call print_int64
+ call print_newline
mov rcx, label2
call print_string
mov eax, [password2]
- call print_int
-
- ; new linhe
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, newline
- mov rdx, 1
- syscall
+ call print_int64
+ call print_newline
mov rax, SYS_CLOSE
mov rdi, r12
@@ -247,68 +226,3 @@ parse_int:
jmp .parse_loop
.done:
ret
-
-print_int:
- mov edi, number_buffer+15 ; write digits from the end
- mov byte [rdi], 0 ; terminator
- dec rdi
-
- cmp eax, 0
- jne .convert
- mov byte [rdi], '0'
- jmp .finish
-.convert:
- ; we will repeatedly compute:
- ; q = eax / 10
- ; r = eax % 10
- ; using only subtraction
-.next_digit:
- mov edx, eax ; tmp = current value
- mov ecx, 0 ; q = 0
-
- cmp edx, 10 ; if < 0, q=0, r=edx
- jb .last_digit
-.sub_loop:
- sub edx, 10
- inc ecx ; q++
- cmp edx, 10
- jae .sub_loop ; while tmp >= 10
-.last_digit:
- ; now:
- ; ecx = quotient
- ; edx = remainder (0..9)
- add dl, '0'
- mov [rdi], dl ; store digit
- dec rdi
- mov eax, ecx ; eax = quotient
- test eax, eax
- jnz .next_digit ; more digits to extract?
-
- inc rdi ; move to first digit
-.finish:
- mov rax, SYS_WRITE
- mov rsi, rdi ; buffer pointer
- mov rdi, STDOUT
- mov rdx, number_buffer+15
- sub rdx, rsi ; length
- syscall
- ret
-
-print_string:
- push rcx
- push rdx
- mov rdx, 0
-.count:
- cmp byte [rcx+rdx], 0
- je .done_count
- inc rdx
- jmp .count
-.done_count:
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, rcx
- syscall
-
- pop rdx
- pop rcx
- ret
diff --git a/aoc-2025/day10.asm b/aoc-2025/day10.asm
index 02582b2..456752c 100644
--- a/aoc-2025/day10.asm
+++ b/aoc-2025/day10.asm
@@ -5,14 +5,7 @@ default rel
global _start
-%define SYS_EXIT 60
-%define SYS_READ 0
-%define SYS_WRITE 1
-%define SYS_OPEN 2
-%define SYS_CLOSE 3
-
-%define O_RDONLY 0
-%define STDOUT 1
+%include "utils/io.asm"
%define RAW_SIZE 262144
%define MAXB 16
@@ -23,8 +16,6 @@ global _start
section .data
input_path db "input/day10.txt", 0
- newline db 10
-
label1 db "Part 1: ", 0
label2 db "Part 2: ", 0
@@ -57,35 +48,14 @@ section .bss
total1 resq 1
total2 resq 1
- number_buffer resb 32
-
section .text
_start:
- mov rax, SYS_OPEN
mov rdi, input_path
- mov rsi, O_RDONLY
- xor rdx, rdx
- syscall
- mov r12, rax
-
- xor r13, r13
-read_loop:
- mov rax, SYS_READ
- mov rdi, r12
- lea rsi, [raw + r13]
+ lea rsi, [raw]
mov rdx, RAW_SIZE
- sub rdx, r13
- syscall
- cmp rax, 0
- jle read_done
- add r13, rax
- jmp read_loop
-read_done:
- mov [raw_len], r13
- mov rax, SYS_CLOSE
- mov rdi, r12
- syscall
+ call read_file
+ mov [raw_len], rax
lea rsi, [raw]
mov rax, [raw_len]
@@ -723,62 +693,3 @@ reduce_row:
jmp .divl
.done:
ret
-
-print_newline:
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, newline
- mov rdx, 1
- syscall
- ret
-
-print_int64:
- mov rdi, number_buffer+31
- mov byte [rdi], 0
- dec rdi
-
- cmp rax, 0
- jne .conv
-
- mov byte [rdi], '0'
- jmp .done
-.conv:
- mov rbx, 10
-.next:
- xor rdx, rdx
- div rbx
- add dl, '0'
- mov [rdi], dl
- dec rdi
- test rax, rax
- jnz .next
-
- inc rdi
-.done:
- mov rax, SYS_WRITE
- mov rsi, rdi
- mov rdi, STDOUT
- mov rdx, number_buffer+31
- sub rdx, rsi
- syscall
- ret
-
-print_string:
- push rcx
- push rdx
- mov rdx, 0
-.length:
- cmp byte [rcx+rdx], 0
- je .submit
- inc rdx
- jmp .length
-.submit:
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, rcx
- syscall
- pop rdx
- pop rcx
- ret
-
-
diff --git a/aoc-2025/day11.asm b/aoc-2025/day11.asm
index bf92fad..c3cd930 100644
--- a/aoc-2025/day11.asm
+++ b/aoc-2025/day11.asm
@@ -5,14 +5,7 @@ default rel
global _start
-%define SYS_EXIT 60
-%define SYS_READ 0
-%define SYS_WRITE 1
-%define SYS_OPEN 2
-%define SYS_CLOSE 3
-
-%define O_RDONLY 0
-%define STDOUT 1
+%include "utils/io.asm"
%define RAW_SIZE 262144
%define NCODES 17576 ; 26^3 possible 3-letter names
@@ -26,8 +19,6 @@ global _start
section .data
input_path db "input/day11.txt", 0
- newline db 10
-
label1 db "Part 1: ", 0
label2 db "Part 2: ", 0
@@ -43,35 +34,14 @@ section .bss
t1 resq 1
t2 resq 1
- number_buffer resb 32
-
section .text
_start:
- mov rax, SYS_OPEN
mov rdi, input_path
- mov rsi, O_RDONLY
- xor rdx, rdx
- syscall
- mov r12, rax
-
- xor r13, r13
-read_loop:
- mov rax, SYS_READ
- mov rdi, r12
- lea rsi, [raw + r13]
+ lea rsi, [raw]
mov rdx, RAW_SIZE
- sub rdx, r13
- syscall
- cmp rax, 0
- jle read_done
- add r13, rax
- jmp read_loop
-read_done:
- mov [raw_len], r13
- mov rax, SYS_CLOSE
- mov rdi, r12
- syscall
+ call read_file
+ mov [raw_len], rax
; memo = -1 everywhere
mov rax, -1
@@ -261,60 +231,3 @@ count:
xor eax, eax
.ret:
ret
-
-print_newline:
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, newline
- mov rdx, 1
- syscall
- ret
-
-print_int64:
- mov rdi, number_buffer+31
- mov byte [rdi], 0
- dec rdi
-
- cmp rax, 0
- jne .conv
-
- mov byte [rdi], '0'
- jmp .done
-.conv:
- mov rbx, 10
-.next:
- xor rdx, rdx
- div rbx
- add dl, '0'
- mov [rdi], dl
- dec rdi
- test rax, rax
- jnz .next
-
- inc rdi
-.done:
- mov rax, SYS_WRITE
- mov rsi, rdi
- mov rdi, STDOUT
- mov rdx, number_buffer+31
- sub rdx, rsi
- syscall
- ret
-
-print_string:
- push rcx
- push rdx
- mov rdx, 0
-.length:
- cmp byte [rcx+rdx], 0
- je .submit
- inc rdx
- jmp .length
-.submit:
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, rcx
- syscall
- pop rdx
- pop rcx
- ret
diff --git a/aoc-2025/day12.asm b/aoc-2025/day12.asm
index 6eb64a9..8931a2b 100644
--- a/aoc-2025/day12.asm
+++ b/aoc-2025/day12.asm
@@ -5,14 +5,8 @@ default rel
global _start
-%define SYS_EXIT 60
-%define SYS_READ 0
-%define SYS_WRITE 1
-%define SYS_OPEN 2
-%define SYS_CLOSE 3
-
-%define O_RDONLY 0
-%define STDOUT 1
+%include "utils/io.asm"
+%include "utils/parse.asm"
%define RAW_SIZE 262144
%define GRID_SIZE 4096 ; regions are at most 50x50
@@ -20,8 +14,6 @@ global _start
section .data
input_path db "input/day12.txt", 0
- newline db 10
-
label1 db "Part 1: ", 0
section .bss
@@ -54,35 +46,14 @@ section .bss
left resq 1
count_feasible resq 1
- number_buffer resb 32
-
section .text
_start:
- mov rax, SYS_OPEN
mov rdi, input_path
- mov rsi, O_RDONLY
- xor rdx, rdx
- syscall
- mov r12, rax
-
- xor r13, r13
-read_loop:
- mov rax, SYS_READ
- mov rdi, r12
- lea rsi, [raw + r13]
+ lea rsi, [raw]
mov rdx, RAW_SIZE
- sub rdx, r13
- syscall
- cmp rax, 0
- jle read_done
- add r13, rax
- jmp read_loop
-read_done:
- mov [raw_len], r13
- mov rax, SYS_CLOSE
- mov rdi, r12
- syscall
+ call read_file
+ mov [raw_len], rax
; parse shapes and regions
lea rsi, [raw]
@@ -106,7 +77,7 @@ pline:
cmp al, '9'
jg maybe_grid
; a number begins the line
- call parse_num
+ call parse_u64
mov r10, rax
mov al, [rsi]
cmp al, 'x'
@@ -127,7 +98,7 @@ region_line:
mov qword [orients_done], 1
.have:
inc rsi ; skip 'x'
- call parse_num
+ call parse_u64
mov r11, rax ; L
.find_colon:
mov al, [rsi]
@@ -145,7 +116,7 @@ region_line:
inc rsi
jmp .rsp
.rsp_done:
- call parse_num
+ call parse_u64
mov [counts + rcx*8], rax
inc rcx
jmp .rcounts
@@ -215,24 +186,6 @@ pdone:
xor rdi, rdi
syscall
-; parse_num: read decimal at [RSI], advancing RSI. Clobbers RAX, RDX.
-parse_num:
- xor rax, rax
-.d:
- mov dl, [rsi]
- cmp dl, '0'
- jl .done
- cmp dl, '9'
- jg .done
- sub dl, '0'
- movzx rdx, dl
- imul rax, rax, 10
- add rax, rdx
- inc rsi
- jmp .d
-.done:
- ret
-
; gen_orients: build the 8 dihedral orientations of every shape as offset lists
; anchored at their row-major-first cell.
gen_orients:
@@ -531,60 +484,3 @@ rec:
pop rbp
pop rbx
ret
-
-print_newline:
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, newline
- mov rdx, 1
- syscall
- ret
-
-print_int64:
- mov rdi, number_buffer+31
- mov byte [rdi], 0
- dec rdi
-
- cmp rax, 0
- jne .conv
-
- mov byte [rdi], '0'
- jmp .done
-.conv:
- mov rbx, 10
-.next:
- xor rdx, rdx
- div rbx
- add dl, '0'
- mov [rdi], dl
- dec rdi
- test rax, rax
- jnz .next
-
- inc rdi
-.done:
- mov rax, SYS_WRITE
- mov rsi, rdi
- mov rdi, STDOUT
- mov rdx, number_buffer+31
- sub rdx, rsi
- syscall
- ret
-
-print_string:
- push rcx
- push rdx
- mov rdx, 0
-.length:
- cmp byte [rcx+rdx], 0
- je .submit
- inc rdx
- jmp .length
-.submit:
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, rcx
- syscall
- pop rdx
- pop rcx
- ret
diff --git a/aoc-2025/day2.asm b/aoc-2025/day2.asm
index c1ae232..987fbf9 100644
--- a/aoc-2025/day2.asm
+++ b/aoc-2025/day2.asm
@@ -5,18 +5,11 @@ default rel
global _start
-%define SYS_EXIT 60
-%define SYS_READ 0
-%define SYS_WRITE 1
-%define SYS_OPEN 2
-%define SYS_CLOSE 3
-
-%define O_RDONLY 0
-%define STDOUT 1
+%include "utils/io.asm"
+%include "utils/parse.asm"
section .data
input_path db "input/day2.txt", 0
- newline db 10
label1 db "Part 1: ", 0
label2 db "Part 2: ", 0
@@ -29,8 +22,6 @@ section .bss
sum1 resq 1
sum2 resq 1
- number_buffer resb 32 ; for printing and number_to_string
-
section .text
_start:
@@ -139,7 +130,7 @@ print_results:
handle_line:
next_range:
; parse start
- call parse_int64
+ call parse_u64
mov r13, rax
cmp byte [rsi], '-'
@@ -147,7 +138,7 @@ next_range:
inc rsi
; parse end
- call parse_int64
+ call parse_u64
mov r14, rax
range_loop:
@@ -186,26 +177,6 @@ after_range:
done_line:
ret
-; RSI points at decimal digits; stops on first non-digit
-parse_int64:
- xor rax, rax
-.parse:
- mov dl, [rsi]
- cmp dl, '0'
- jl .done
- cmp dl, '9'
- jg .done
-
- sub dl, '0'
- movzx rdx, dl
- imul rax, rax, 10
- add rax, rdx
-
- inc rsi
- jmp .parse
-.done:
- ret
-
; number_to_string: convert RAX to decimal ASCII, MSB-first
; Output:
; RSI = pointer to first digit
@@ -351,60 +322,3 @@ check_invalid2:
pop rdx
pop rbx
ret
-
-print_newline:
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, newline
- mov rdx, 1
- syscall
- ret
-
-print_int64:
- mov rdi, number_buffer+31
- mov byte [rdi], 0
- dec rdi
-
- cmp rax, 0
- jne .conv
-
- mov byte [rdi], '0'
- jmp .done
-.conv:
- mov rbx, 10
-.next:
- xor rdx, rdx
- div rbx
- add dl, '0'
- mov [rdi], dl
- dec rdi
- test rax, rax
- jnz .next
-
- inc rdi
-.done:
- mov rax, SYS_WRITE
- mov rsi, rdi
- mov rdi, STDOUT
- mov rdx, number_buffer+31
- sub rdx, rsi
- syscall
- ret
-
-print_string:
- push rcx
- push rdx
- mov rdx, 0
-.length:
- cmp byte [rcx+rdx], 0
- je .submit
- inc rdx
- jmp .length
-.submit:
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, rcx
- syscall
- pop rdx
- pop rcx
- ret
diff --git a/aoc-2025/day3.asm b/aoc-2025/day3.asm
index c8b8b75..8330755 100644
--- a/aoc-2025/day3.asm
+++ b/aoc-2025/day3.asm
@@ -5,20 +5,11 @@ default rel
global _start
-%define SYS_EXIT 60
-%define SYS_READ 0
-%define SYS_WRITE 1
-%define SYS_OPEN 2
-%define SYS_CLOSE 3
-
-%define O_RDONLY 0
-%define STDOUT 1
+%include "utils/io.asm"
section .data
input_path db "input/day3.txt", 0
- newline db 10
-
label1 db "Part 1: ", 0
label2 db "Part 2: ", 0
@@ -31,7 +22,6 @@ section .bss
sum2 resq 1
work_digits resb 64 ; stack for greedy subsequence
- number_buffer resb 32 ; for printing
section .text
@@ -242,60 +232,3 @@ get_max_for_k:
jmp .convert_loop
.done:
ret
-
-print_newline:
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, newline
- mov rdx, 1
- syscall
- ret
-
-print_int64:
- mov rdi, number_buffer+31
- mov byte [rdi], 0
- dec rdi
-
- cmp rax, 0
- jne .conv
-
- mov byte [rdi], '0'
- jmp .done
-.conv:
- mov rbx, 10
-.next:
- xor rdx, rdx
- div rbx
- add dl, '0'
- mov [rdi], dl
- dec rdi
- test rax, rax
- jnz .next
-
- inc rdi
-.done:
- mov rax, SYS_WRITE
- mov rsi, rdi
- mov rdi, STDOUT
- mov rdx, number_buffer+31
- sub rdx, rsi
- syscall
- ret
-
-print_string:
- push rcx
- push rdx
- mov rdx, 0
-.length:
- cmp byte [rcx+rdx], 0
- je .submit
- inc rdx
- jmp .length
-.submit:
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, rcx
- syscall
- pop rdx
- pop rcx
- ret
diff --git a/aoc-2025/day4.asm b/aoc-2025/day4.asm
index 57867b1..60e53ec 100644
--- a/aoc-2025/day4.asm
+++ b/aoc-2025/day4.asm
@@ -5,14 +5,7 @@ default rel
global _start
-%define SYS_EXIT 60
-%define SYS_READ 0
-%define SYS_WRITE 1
-%define SYS_OPEN 2
-%define SYS_CLOSE 3
-
-%define O_RDONLY 0
-%define STDOUT 1
+%include "utils/io.asm"
%define RAW_SIZE 4194304 ; 4 MiB scratch for the raw file
%define GRID_SIZE 4194304 ; 4 MiB for the padded grid / mark buffers
@@ -20,8 +13,6 @@ global _start
section .data
input_path db "input/day4.txt", 0
- newline db 10
-
label1 db "Part 1: ", 0
label2 db "Part 2: ", 0
@@ -38,37 +29,14 @@ section .bss
part1 resq 1
part2 resq 1
- number_buffer resb 32 ; for printing
-
section .text
_start:
- mov rax, SYS_OPEN
mov rdi, input_path
- mov rsi, O_RDONLY
- xor rdx, rdx
- syscall
- mov r12, rax ; fd
-
- xor r13, r13 ; bytes read so far
-read_loop:
- mov rax, SYS_READ
- mov rdi, r12
- lea rsi, [raw + r13]
+ lea rsi, [raw]
mov rdx, RAW_SIZE
- sub rdx, r13 ; remaining capacity
- syscall
-
- cmp rax, 0
- jle read_done
- add r13, rax
- jmp read_loop
-read_done:
- mov [raw_len], r13
-
- mov rax, SYS_CLOSE
- mov rdi, r12
- syscall
+ call read_file
+ mov [raw_len], rax
xor rcx, rcx ; column scanner
width_scan:
@@ -266,60 +234,3 @@ count_neighbors:
movzx r8d, byte [grid + rdx + 1]
add eax, r8d
ret
-
-print_newline:
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, newline
- mov rdx, 1
- syscall
- ret
-
-print_int64:
- mov rdi, number_buffer+31
- mov byte [rdi], 0
- dec rdi
-
- cmp rax, 0
- jne .conv
-
- mov byte [rdi], '0'
- jmp .done
-.conv:
- mov rbx, 10
-.next:
- xor rdx, rdx
- div rbx
- add dl, '0'
- mov [rdi], dl
- dec rdi
- test rax, rax
- jnz .next
-
- inc rdi
-.done:
- mov rax, SYS_WRITE
- mov rsi, rdi
- mov rdi, STDOUT
- mov rdx, number_buffer+31
- sub rdx, rsi
- syscall
- ret
-
-print_string:
- push rcx
- push rdx
- mov rdx, 0
-.length:
- cmp byte [rcx+rdx], 0
- je .submit
- inc rdx
- jmp .length
-.submit:
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, rcx
- syscall
- pop rdx
- pop rcx
- ret
diff --git a/aoc-2025/day5.asm b/aoc-2025/day5.asm
index 4f395a0..4718343 100644
--- a/aoc-2025/day5.asm
+++ b/aoc-2025/day5.asm
@@ -5,14 +5,8 @@ default rel
global _start
-%define SYS_EXIT 60
-%define SYS_READ 0
-%define SYS_WRITE 1
-%define SYS_OPEN 2
-%define SYS_CLOSE 3
-
-%define O_RDONLY 0
-%define STDOUT 1
+%include "utils/io.asm"
+%include "utils/parse.asm"
%define RAW_SIZE 1048576 ; 1 MiB scratch for the raw file
%define MAX_RANGES 8192 ; plenty for the ~177 input ranges
@@ -20,8 +14,6 @@ global _start
section .data
input_path db "input/day5.txt", 0
- newline db 10
-
label1 db "Part 1: ", 0
label2 db "Part 2: ", 0
@@ -38,36 +30,14 @@ section .bss
part1 resq 1
part2 resq 1
- number_buffer resb 32
-
section .text
_start:
- mov rax, SYS_OPEN
mov rdi, input_path
- mov rsi, O_RDONLY
- xor rdx, rdx
- syscall
- mov r12, rax ; fd
-
- xor r13, r13
-read_loop:
- mov rax, SYS_READ
- mov rdi, r12
- lea rsi, [raw + r13]
+ lea rsi, [raw]
mov rdx, RAW_SIZE
- sub rdx, r13
- syscall
- cmp rax, 0
- jle read_done
- add r13, rax
- jmp read_loop
-read_done:
- mov [raw_len], r13
-
- mov rax, SYS_CLOSE
- mov rdi, r12
- syscall
+ call read_file
+ mov [raw_len], rax
; RSI = cursor, R14 = end pointer (both preserved across helper calls)
lea rsi, [raw]
@@ -146,25 +116,6 @@ print_results:
xor rdi, rdi
syscall
-; parse_u64: read decimal digits at [RSI], advancing RSI past them.
-; Output: RAX = value. Stops on the first non-digit. Clobbers RAX, RDX.
-parse_u64:
- xor rax, rax
-.digit:
- mov dl, [rsi]
- cmp dl, '0'
- jl .done
- cmp dl, '9'
- jg .done
- sub dl, '0'
- movzx rdx, dl
- imul rax, rax, 10
- add rax, rdx
- inc rsi
- jmp .digit
-.done:
- ret
-
; is_fresh: test membership of an ID in the merged intervals.
; Input: RDI = id
; Output: RAX = 1 if the id lies in any interval, else 0
@@ -272,60 +223,3 @@ finalize_ranges:
inc rdx ; end - start + 1
add r12, rdx
ret
-
-print_newline:
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, newline
- mov rdx, 1
- syscall
- ret
-
-print_int64:
- mov rdi, number_buffer+31
- mov byte [rdi], 0
- dec rdi
-
- cmp rax, 0
- jne .conv
-
- mov byte [rdi], '0'
- jmp .done
-.conv:
- mov rbx, 10
-.next:
- xor rdx, rdx
- div rbx
- add dl, '0'
- mov [rdi], dl
- dec rdi
- test rax, rax
- jnz .next
-
- inc rdi
-.done:
- mov rax, SYS_WRITE
- mov rsi, rdi
- mov rdi, STDOUT
- mov rdx, number_buffer+31
- sub rdx, rsi
- syscall
- ret
-
-print_string:
- push rcx
- push rdx
- mov rdx, 0
-.length:
- cmp byte [rcx+rdx], 0
- je .submit
- inc rdx
- jmp .length
-.submit:
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, rcx
- syscall
- pop rdx
- pop rcx
- ret
diff --git a/aoc-2025/day6.asm b/aoc-2025/day6.asm
index 774ca4c..728b8b0 100644
--- a/aoc-2025/day6.asm
+++ b/aoc-2025/day6.asm
@@ -5,14 +5,7 @@ default rel
global _start
-%define SYS_EXIT 60
-%define SYS_READ 0
-%define SYS_WRITE 1
-%define SYS_OPEN 2
-%define SYS_CLOSE 3
-
-%define O_RDONLY 0
-%define STDOUT 1
+%include "utils/io.asm"
%define RAW_SIZE 1048576
%define MAX_W 8192
@@ -22,8 +15,6 @@ global _start
section .data
input_path db "input/day6.txt", 0
- newline db 10
-
label1 db "Part 1: ", 0
label2 db "Part 2: ", 0
@@ -42,36 +33,14 @@ section .bss
part1 resq 1
part2 resq 1
- number_buffer resb 32
-
section .text
_start:
- mov rax, SYS_OPEN
mov rdi, input_path
- mov rsi, O_RDONLY
- xor rdx, rdx
- syscall
- mov r12, rax
-
- xor r13, r13
-read_loop:
- mov rax, SYS_READ
- mov rdi, r12
- lea rsi, [raw + r13]
+ lea rsi, [raw]
mov rdx, RAW_SIZE
- sub rdx, r13
- syscall
- cmp rax, 0
- jle read_done
- add r13, rax
- jmp read_loop
-read_done:
- mov [raw_len], r13
-
- mov rax, SYS_CLOSE
- mov rdi, r12
- syscall
+ call read_file
+ mov [raw_len], rax
; width = length of the first line
xor rcx, rcx
@@ -360,60 +329,3 @@ process_block:
add [part2], r13
.ret:
ret
-
-print_newline:
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, newline
- mov rdx, 1
- syscall
- ret
-
-print_int64:
- mov rdi, number_buffer+31
- mov byte [rdi], 0
- dec rdi
-
- cmp rax, 0
- jne .conv
-
- mov byte [rdi], '0'
- jmp .done
-.conv:
- mov rbx, 10
-.next:
- xor rdx, rdx
- div rbx
- add dl, '0'
- mov [rdi], dl
- dec rdi
- test rax, rax
- jnz .next
-
- inc rdi
-.done:
- mov rax, SYS_WRITE
- mov rsi, rdi
- mov rdi, STDOUT
- mov rdx, number_buffer+31
- sub rdx, rsi
- syscall
- ret
-
-print_string:
- push rcx
- push rdx
- mov rdx, 0
-.length:
- cmp byte [rcx+rdx], 0
- je .submit
- inc rdx
- jmp .length
-.submit:
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, rcx
- syscall
- pop rdx
- pop rcx
- ret
diff --git a/aoc-2025/day7.asm b/aoc-2025/day7.asm
index 40d700d..1d990a7 100644
--- a/aoc-2025/day7.asm
+++ b/aoc-2025/day7.asm
@@ -5,14 +5,7 @@ default rel
global _start
-%define SYS_EXIT 60
-%define SYS_READ 0
-%define SYS_WRITE 1
-%define SYS_OPEN 2
-%define SYS_CLOSE 3
-
-%define O_RDONLY 0
-%define STDOUT 1
+%include "utils/io.asm"
%define RAW_SIZE 1048576
%define MAX_W 1024
@@ -22,8 +15,6 @@ global _start
section .data
input_path db "input/day7.txt", 0
- newline db 10
-
label1 db "Part 1: ", 0
label2 db "Part 2: ", 0
@@ -43,36 +34,14 @@ section .bss
part1 resq 1
part2 resq 1
- number_buffer resb 32
-
section .text
_start:
- mov rax, SYS_OPEN
mov rdi, input_path
- mov rsi, O_RDONLY
- xor rdx, rdx
- syscall
- mov r12, rax
-
- xor r13, r13
-read_loop:
- mov rax, SYS_READ
- mov rdi, r12
- lea rsi, [raw + r13]
+ lea rsi, [raw]
mov rdx, RAW_SIZE
- sub rdx, r13
- syscall
- cmp rax, 0
- jle read_done
- add r13, rax
- jmp read_loop
-read_done:
- mov [raw_len], r13
-
- mov rax, SYS_CLOSE
- mov rdi, r12
- syscall
+ call read_file
+ mov [raw_len], rax
; width = length of the first line
xor rcx, rcx
@@ -331,60 +300,3 @@ print_results:
mov rax, SYS_EXIT
xor rdi, rdi
syscall
-
-print_newline:
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, newline
- mov rdx, 1
- syscall
- ret
-
-print_int64:
- mov rdi, number_buffer+31
- mov byte [rdi], 0
- dec rdi
-
- cmp rax, 0
- jne .conv
-
- mov byte [rdi], '0'
- jmp .done
-.conv:
- mov rbx, 10
-.next:
- xor rdx, rdx
- div rbx
- add dl, '0'
- mov [rdi], dl
- dec rdi
- test rax, rax
- jnz .next
-
- inc rdi
-.done:
- mov rax, SYS_WRITE
- mov rsi, rdi
- mov rdi, STDOUT
- mov rdx, number_buffer+31
- sub rdx, rsi
- syscall
- ret
-
-print_string:
- push rcx
- push rdx
- mov rdx, 0
-.length:
- cmp byte [rcx+rdx], 0
- je .submit
- inc rdx
- jmp .length
-.submit:
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, rcx
- syscall
- pop rdx
- pop rcx
- ret
diff --git a/aoc-2025/day8.asm b/aoc-2025/day8.asm
index 407d0e4..6a4ecec 100644
--- a/aoc-2025/day8.asm
+++ b/aoc-2025/day8.asm
@@ -5,14 +5,8 @@ default rel
global _start
-%define SYS_EXIT 60
-%define SYS_READ 0
-%define SYS_WRITE 1
-%define SYS_OPEN 2
-%define SYS_CLOSE 3
-
-%define O_RDONLY 0
-%define STDOUT 1
+%include "utils/io.asm"
+%include "utils/parse.asm"
%define RAW_SIZE 262144
%define MAXN 1024
@@ -22,8 +16,6 @@ global _start
section .data
input_path db "input/day8.txt", 0
- newline db 10
-
label1 db "Part 1: ", 0
label2 db "Part 2: ", 0
@@ -49,36 +41,14 @@ section .bss
part1 resq 1
part2 resq 1
- number_buffer resb 32
-
section .text
_start:
- mov rax, SYS_OPEN
mov rdi, input_path
- mov rsi, O_RDONLY
- xor rdx, rdx
- syscall
- mov r12, rax
-
- xor r13, r13
-read_loop:
- mov rax, SYS_READ
- mov rdi, r12
- lea rsi, [raw + r13]
+ lea rsi, [raw]
mov rdx, RAW_SIZE
- sub rdx, r13
- syscall
- cmp rax, 0
- jle read_done
- add r13, rax
- jmp read_loop
-read_done:
- mov [raw_len], r13
-
- mov rax, SYS_CLOSE
- mov rdi, r12
- syscall
+ call read_file
+ mov [raw_len], rax
; parse "X,Y,Z" lines into x/y/z, counting boxes
lea rsi, [raw]
@@ -354,78 +324,3 @@ compute_part1:
imul rax, r10
mov [part1], rax
ret
-
-; parse_u64: read decimal digits at [RSI], advancing RSI. Clobbers RAX, RDX.
-parse_u64:
- xor rax, rax
-.digit:
- mov dl, [rsi]
- cmp dl, '0'
- jl .done
- cmp dl, '9'
- jg .done
- sub dl, '0'
- movzx rdx, dl
- imul rax, rax, 10
- add rax, rdx
- inc rsi
- jmp .digit
-.done:
- ret
-
-print_newline:
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, newline
- mov rdx, 1
- syscall
- ret
-
-print_int64:
- mov rdi, number_buffer+31
- mov byte [rdi], 0
- dec rdi
-
- cmp rax, 0
- jne .conv
-
- mov byte [rdi], '0'
- jmp .done
-.conv:
- mov rbx, 10
-.next:
- xor rdx, rdx
- div rbx
- add dl, '0'
- mov [rdi], dl
- dec rdi
- test rax, rax
- jnz .next
-
- inc rdi
-.done:
- mov rax, SYS_WRITE
- mov rsi, rdi
- mov rdi, STDOUT
- mov rdx, number_buffer+31
- sub rdx, rsi
- syscall
- ret
-
-print_string:
- push rcx
- push rdx
- mov rdx, 0
-.length:
- cmp byte [rcx+rdx], 0
- je .submit
- inc rdx
- jmp .length
-.submit:
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, rcx
- syscall
- pop rdx
- pop rcx
- ret
diff --git a/aoc-2025/day9.asm b/aoc-2025/day9.asm
index 8b0edcf..e5a7d0d 100644
--- a/aoc-2025/day9.asm
+++ b/aoc-2025/day9.asm
@@ -5,14 +5,8 @@ default rel
global _start
-%define SYS_EXIT 60
-%define SYS_READ 0
-%define SYS_WRITE 1
-%define SYS_OPEN 2
-%define SYS_CLOSE 3
-
-%define O_RDONLY 0
-%define STDOUT 1
+%include "utils/io.asm"
+%include "utils/parse.asm"
%define RAW_SIZE 262144
%define MAXN 512
@@ -23,8 +17,6 @@ global _start
section .data
input_path db "input/day9.txt", 0
- newline db 10
-
label1 db "Part 1: ", 0
label2 db "Part 2: ", 0
@@ -62,35 +54,14 @@ section .bss
best1 resq 1
best2 resq 1
- number_buffer resb 32
-
section .text
_start:
- mov rax, SYS_OPEN
mov rdi, input_path
- mov rsi, O_RDONLY
- xor rdx, rdx
- syscall
- mov r12, rax
-
- xor r13, r13
-read_loop:
- mov rax, SYS_READ
- mov rdi, r12
- lea rsi, [raw + r13]
+ lea rsi, [raw]
mov rdx, RAW_SIZE
- sub rdx, r13
- syscall
- cmp rax, 0
- jle read_done
- add r13, rax
- jmp read_loop
-read_done:
- mov [raw_len], r13
- mov rax, SYS_CLOSE
- mov rdi, r12
- syscall
+ call read_file
+ mov [raw_len], rax
; parse "X,Y" vertices in order
lea rsi, [raw]
@@ -567,78 +538,3 @@ dedup_q:
jmp .loop
.done:
ret
-
-; parse_u64: read decimal digits at [RSI], advancing RSI. Clobbers RAX, RDX.
-parse_u64:
- xor rax, rax
-.digit:
- mov dl, [rsi]
- cmp dl, '0'
- jl .done
- cmp dl, '9'
- jg .done
- sub dl, '0'
- movzx rdx, dl
- imul rax, rax, 10
- add rax, rdx
- inc rsi
- jmp .digit
-.done:
- ret
-
-print_newline:
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, newline
- mov rdx, 1
- syscall
- ret
-
-print_int64:
- mov rdi, number_buffer+31
- mov byte [rdi], 0
- dec rdi
-
- cmp rax, 0
- jne .conv
-
- mov byte [rdi], '0'
- jmp .done
-.conv:
- mov rbx, 10
-.next:
- xor rdx, rdx
- div rbx
- add dl, '0'
- mov [rdi], dl
- dec rdi
- test rax, rax
- jnz .next
-
- inc rdi
-.done:
- mov rax, SYS_WRITE
- mov rsi, rdi
- mov rdi, STDOUT
- mov rdx, number_buffer+31
- sub rdx, rsi
- syscall
- ret
-
-print_string:
- push rcx
- push rdx
- mov rdx, 0
-.length:
- cmp byte [rcx+rdx], 0
- je .submit
- inc rdx
- jmp .length
-.submit:
- mov rax, SYS_WRITE
- mov rdi, STDOUT
- mov rsi, rcx
- syscall
- pop rdx
- pop rcx
- ret
diff --git a/aoc-2025/utils/io.asm b/aoc-2025/utils/io.asm
new file mode 100644
index 0000000..2081671
--- /dev/null
+++ b/aoc-2025/utils/io.asm
@@ -0,0 +1,107 @@
+; utils/io.asm - shared syscall constants, file reading, and output helpers.
+; This file is %included (not linked) by each day's solution.
+
+%define SYS_EXIT 60
+%define SYS_READ 0
+%define SYS_WRITE 1
+%define SYS_OPEN 2
+%define SYS_CLOSE 3
+
+%define O_RDONLY 0
+%define STDOUT 1
+
+section .data
+ newline db 10
+
+section .bss
+ number_buffer resb 32
+
+section .text
+
+; read_file: open the path in RDI read-only, read up to RDX bytes into the
+; buffer in RSI, close, and return the number of bytes read in RAX.
+read_file:
+ mov r8, rsi ; buffer base
+ mov r9, rdx ; capacity
+ mov rax, SYS_OPEN
+ mov rsi, O_RDONLY
+ xor rdx, rdx
+ syscall
+ mov r10, rax ; fd
+ xor r11, r11 ; bytes read so far
+.loop:
+ mov rax, SYS_READ
+ mov rdi, r10
+ lea rsi, [r8 + r11]
+ mov rdx, r9
+ sub rdx, r11
+ syscall
+ cmp rax, 0
+ jle .done
+ add r11, rax
+ jmp .loop
+.done:
+ mov rax, SYS_CLOSE
+ mov rdi, r10
+ syscall
+ mov rax, r11
+ ret
+
+print_newline:
+ mov rax, SYS_WRITE
+ mov rdi, STDOUT
+ mov rsi, newline
+ mov rdx, 1
+ syscall
+ ret
+
+; print_int64: print the unsigned integer in RAX in decimal.
+print_int64:
+ mov rdi, number_buffer+31
+ mov byte [rdi], 0
+ dec rdi
+
+ cmp rax, 0
+ jne .conv
+
+ mov byte [rdi], '0'
+ jmp .done
+.conv:
+ mov rbx, 10
+.next:
+ xor rdx, rdx
+ div rbx
+ add dl, '0'
+ mov [rdi], dl
+ dec rdi
+ test rax, rax
+ jnz .next
+
+ inc rdi
+.done:
+ mov rax, SYS_WRITE
+ mov rsi, rdi
+ mov rdi, STDOUT
+ mov rdx, number_buffer+31
+ sub rdx, rsi
+ syscall
+ ret
+
+; print_string: print the NUL-terminated string pointed to by RCX.
+print_string:
+ push rcx
+ push rdx
+ mov rdx, 0
+.length:
+ cmp byte [rcx+rdx], 0
+ je .submit
+ inc rdx
+ jmp .length
+.submit:
+ mov rax, SYS_WRITE
+ mov rdi, STDOUT
+ mov rsi, rcx
+ syscall
+ pop rdx
+ pop rcx
+ ret
diff --git a/aoc-2025/utils/parse.asm b/aoc-2025/utils/parse.asm
new file mode 100644
index 0000000..833cb4e
--- /dev/null
+++ b/aoc-2025/utils/parse.asm
@@ -0,0 +1,22 @@
+; utils/parse.asm - decimal parsing helper.
+
+section .text
+
+; parse_u64: read decimal digits at [RSI] into RAX, advancing RSI past them.
+; Stops on the first non-digit. Clobbers RAX, RDX.
+parse_u64:
+ xor rax, rax
+.digit:
+ mov dl, [rsi]
+ cmp dl, '0'
+ jl .done
+ cmp dl, '9'
+ jg .done
+ sub dl, '0'
+ movzx rdx, dl
+ imul rax, rax, 10
+ add rax, rdx
+ inc rsi
+ jmp .digit
+.done:
+ ret