From 054d372a716bca4f628674e524e3d027f6824019 Mon Sep 17 00:00:00 2001 From: hachem Date: Sun, 6 Sep 2026 04:12:25 +0200 Subject: refactor: clean up repository layout --- 2025/day1.asm | 228 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 2025/day1.asm (limited to '2025/day1.asm') diff --git a/2025/day1.asm b/2025/day1.asm new file mode 100644 index 0000000..928e7a5 --- /dev/null +++ b/2025/day1.asm @@ -0,0 +1,228 @@ +; Advent of Code 2025 - Day 1 + +bits 64 +default rel + +global _start + +%include "utils/io.asm" + +section .data + input_path db "input/day1.txt", 0 + + label1 db "Password 1: ", 0 + label2 db "Password 2: ", 0 + + angle1 dd 50 + angle2 dd 50 + + password1 dd 0 + password2 dd 0 + +section .bss + buffer resb 4096 + line_buffer resb 256 + line_len resd 1 + +section .text + +_start: + ; open file + mov rax, SYS_OPEN + mov rdi, input_path + mov rsi, O_RDONLY + xor rdx, rdx + syscall + + mov r12, rax ; fd in R12 + mov dword [line_len], 0 ; no chars in current line yet + +read_loop: + ; read up to 4096 bytes + mov rax, SYS_READ + mov rdi, r12 + mov rsi, buffer + mov rdx, 4096 + syscall + + cmp rax, 0 + jle eof ; <=0 -> EOF or error + + mov rdi, buffer ; scan pointer + mov rbp, rax ; bytes remaining in this chunk + +scan_chunk: + cmp rbp, 0 + je read_loop ; chunk done, read next + + mov al, [rdi] + + ; windows can be a fucking bitch + ; handle (CR) -> just skip + cmp al, 13 + je skip_cr + + ; handle LF (10) -> end of line + cmp al, 10 + je end_of_line + + ; normal character -> append to line_buffer if space left + mov edx, [line_len] + cmp edx, 255 ; leave 1 byte for NULL + jae skip_store ; ignore extra characters if too long + mov [line_buffer+rdx], al + inc edx + mov [line_len], edx + +skip_store: + inc rdi + dec rbp + jmp scan_chunk + +skip_cr: + inc rdi + dec rbp + jmp scan_chunk + +end_of_line: + ; terminate current line + mov edx, [line_len] + mov byte [line_buffer+rdx], 0 + + ; if line isn't empty, process it + cmp edx, 0 + je line_done + + push rdi + mov rsi, line_buffer + call handle_line + pop rdi + +line_done: + mov dword [line_len], 0 ; reset line length + inc rdi + dec rbp + jmp scan_chunk + +; process last line if not newline-terminated, then print result +eof: + ; if there is a partial line at EOF, process it + mov edx, [line_len] + cmp edx, 0 + jle print_results + mov byte [line_buffer+rdx], 0 + + mov rsi, line_buffer + call handle_line + +print_results: + mov rcx, label1 + call print_string + mov eax, [password1] + call print_int64 + call print_newline + + mov rcx, label2 + call print_string + mov eax, [password2] + call print_int64 + call print_newline + + mov rax, SYS_CLOSE + mov rdi, r12 + syscall + mov rax, SYS_EXIT + xor rdi, rdi + syscall + +; Handle one line: RSI -> "L123" or "R45" +handle_line: + mov al, [rsi] + cmp al, 'L' + je .left + mov ebx, 1 ; direction = +1 for 'R' or anything else + jmp .after +.left: + mov ebx, -1 ; direction = -1 for 'L' +.after: + inc rsi ; skip 'L' or 'R' + call parse_int ; EAX = steps + mov ecx, eax + +; Part 1 +p1_start: + mov eax, ecx + imul eax, ebx + add eax, [angle1] + call normalize_angle + mov [angle1], eax + cmp eax, 0 + jne p2_start + mov rdi, password1 + mov edx, [rdi] + inc edx + mov [rdi], edx + +; Part 2 +p2_start: + mov rdi, password2 +.loop: + test ecx, ecx + jle p2_exit + dec ecx + + mov eax, [angle2] + call update_angle_count + mov [angle2], eax + + jmp .loop +p2_exit: + ret + +; normalize eax to 0..99 +normalize_angle: + cmp eax, 0 + jl .add + cmp eax, 100 + jl .done + sub eax, 100 + jmp normalize_angle +.add: + add eax, 100 + jmp normalize_angle +.done: + ret + +; eax = angle, ebx = direction, rdi = password counter addr +update_angle_count: + add eax, ebx + call normalize_angle + + cmp eax, 0 + jne .done + mov edx, [rdi] + inc edx + mov [rdi], edx +.done: + ret + +; parse ASCII integer into EAX +parse_int: + xor eax, eax ; result = 0 +.parse_loop: + mov dl, [rsi] + cmp dl, '0' + jl .done + cmp dl, '9' + jg .done + + sub dl, '0' ; digit value 0..9 + movzx edx, dl + + imul eax, eax, 10 ; result *= 10 + add eax, edx ; result += digit + + inc rsi + jmp .parse_loop +.done: + ret -- cgit v1.3