From 78c4d3d06d8e863cfe2489281ccfe206544cbd7f Mon Sep 17 00:00:00 2001 From: hachem Date: Sun, 6 Sep 2026 00:40:37 +0200 Subject: fix: add utilities --- Makefile | 6 ++- aoc-2025/day1.asm | 96 ++----------------------------------- aoc-2025/day10.asm | 97 ++------------------------------------ aoc-2025/day11.asm | 95 ++----------------------------------- aoc-2025/day12.asm | 120 ++++------------------------------------------- aoc-2025/day2.asm | 94 ++----------------------------------- aoc-2025/day3.asm | 69 +-------------------------- aoc-2025/day4.asm | 97 ++------------------------------------ aoc-2025/day5.asm | 116 ++------------------------------------------- aoc-2025/day6.asm | 96 ++----------------------------------- aoc-2025/day7.asm | 96 ++----------------------------------- aoc-2025/day8.asm | 115 ++------------------------------------------- aoc-2025/day9.asm | 114 ++------------------------------------------ aoc-2025/utils/io.asm | 107 ++++++++++++++++++++++++++++++++++++++++++ aoc-2025/utils/parse.asm | 22 +++++++++ 15 files changed, 186 insertions(+), 1154 deletions(-) create mode 100644 aoc-2025/utils/io.asm create mode 100644 aoc-2025/utils/parse.asm diff --git a/Makefile b/Makefile index 817247b..5da61f2 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,8 @@ LDFLAGS ?= -m elf_x86_64 DAYS := $(basename $(notdir $(wildcard $(SRC_DIR)/day*.asm))) BINARIES := $(addprefix $(BUILD_DIR)/,$(DAYS)) +UTILS := $(wildcard $(SRC_DIR)/utils/*.asm) + .PHONY: all clean list run all: $(BINARIES) @@ -20,8 +22,8 @@ all: $(BINARIES) $(BUILD_DIR): @mkdir -p $@ -$(BUILD_DIR)/%.o: $(SRC_DIR)/%.asm | $(BUILD_DIR) - @$(NASM) $(NASMFLAGS) $< -o $@ +$(BUILD_DIR)/%.o: $(SRC_DIR)/%.asm $(UTILS) | $(BUILD_DIR) + @$(NASM) $(NASMFLAGS) -I$(SRC_DIR)/ $< -o $@ $(BUILD_DIR)/%: $(BUILD_DIR)/%.o @$(LD) $(LDFLAGS) -o $@ $< 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 -- cgit v1.3