adventofcode2023/03/main.s
2023-12-03 02:52:09 -06:00

190 lines
3.9 KiB
ArmAsm

%define BUFF_LIM 32768
;%define GRID_X 10
;%define GRID_Y 10
%define GRID_X 140
%define GRID_Y 140
global _start
[bits 32]
[section .text]
%include "utils.s"
_start:
mov ebx, filename
call open_file
mov ecx, read_buff
mov edx, BUFF_LIM
call read_file
add eax, read_buff
mov [file_lim], eax
; 1. read file into array,
; padding edges by 1
read_to_array:
mov esi, read_buff
; first line padded by .
mov edi, array
mov ecx, (GRID_X+2)
mov al, '.'
rep stosb
mov ecx, GRID_Y ; line count
.read_lines:
; 1 char pad before line
mov al, '.'
stosb
push ecx
.read_chars:
mov ecx, GRID_X ; line len (discluding newline)
rep movsb ; copy line
inc esi ; skip newline
mov al, '.'
stosb ; pad with .
pop ecx
loop .read_lines
; fill last line with .
mov ecx, (GRID_X+2)
mov al, '.'
rep stosb
; 2. find numbers, putting indexes
; into numbers array in the index array
find_numbers:
push 1 ; current number index
xor ecx, ecx ; index
.find_next:
; check for end of array
cmp ecx, (GRID_X+2)*(GRID_Y*2)
jge .done
lea esi, [ecx+array] ; current char
mov edi, esi ; number start if num
call dec_parse
jnc .has_num
; no number
inc ecx
jmp .find_next
.has_num:
sub esi, edi ; get number char length
add esi, ecx ; add to index
dec esi
; write to index and to numbers
pop ebx ; cur num idx
mov [numbers+ebx*4], eax ; save number value
.write_idx:
mov [index+ecx*2], bx
; overwrite digits with .
mov byte [array+ecx], '.'
inc ecx
cmp ecx, esi
jl .write_idx
inc ecx
; push new cur num idx
inc ebx
push ebx
jmp .find_next
.done:
add esp, 4 ; no more cur num idx
; 3. go through array, checking the neighbors of
; numbers for symbols, skip *last added index*,
; if has * as neighbor, replace the index of the *
; with the current number index if it has no index currently,
; otherwise multiply by the number its index points to
; and add to final_value, setting last added index to current index
check_neighbors:
xor ecx, ecx ; index
dec ecx ; gets incremented immediately
xor ebx, ebx ; last added idx
mov esi, array
mov edi, index
.check_next_number:
; check for end of array
inc ecx
cmp ecx, (GRID_X+2)*(GRID_Y*2)
jge .done
; check if num
movzx eax, word [index+ecx*2]
test eax, eax
jz .check_next_number
.found_num:
; check if last added idx
cmp eax, ebx
je .check_next_number ; is last added idx, skip
.check_symbols:
lea edx, [ecx+array] ; current char
; right
lea ebp, [ecx+1]
cmp byte [edx+1], '*'
je .has_sym_neighbor
; left
lea ebp, [ecx-1]
cmp byte [edx-1], '*'
je .has_sym_neighbor
; top
lea ebp, [ecx-(GRID_X+2)]
cmp byte [edx-(GRID_X+2)], '*'
je .has_sym_neighbor
; bottom
lea ebp, [ecx+(GRID_X+2)]
cmp byte [edx+(GRID_X+2)], '*'
je .has_sym_neighbor
; top left
lea ebp, [ecx-((GRID_X+2)+1)]
cmp byte [edx-((GRID_X+2)+1)], '*'
je .has_sym_neighbor
; top right
lea ebp, [ecx-((GRID_X+2)-1)]
cmp byte [edx-((GRID_X+2)-1)], '*'
je .has_sym_neighbor
; bottom left
lea ebp, [ecx+((GRID_X+2)-1)]
cmp byte [edx+((GRID_X+2)-1)], '*'
je .has_sym_neighbor
; bottom right
lea ebp, [ecx+((GRID_X+2)+1)]
cmp byte [edx+((GRID_X+2)+1)], '*'
je .has_sym_neighbor
; there's no symbol neighbor
; get next number
jmp .check_next_number
.has_sym_neighbor:
; we have a symbol neighbor!
; get its id
movzx edx, word [index+ebp*2]
test edx, edx
jz .no_sym_number ; * doesn't have a number assigned yet
; multiply by its number!
pushad ; out of registers lol
mov eax, [numbers+eax*4] ; our number
mul dword [numbers+edx*4] ; * number
; add to final value
add [final_value], eax
popad ; get back values :3
; set last added idx
mov ebx, eax
; get next number
jmp .check_next_number
.no_sym_number:
; save our index in the * index
mov [index+ebp*2], ax
; set last added idx
mov ebx, eax
; get next number
jmp .check_next_number
.done:
; we can print final value
mov eax, [final_value]
call print_dec
jmp exit
[section .data]
file_lim: dd 0
final_value: dd 0
filename: db "input",0
[section .bss]
numbers: resd 2048
array: resb (GRID_X+2)*(GRID_Y*2)
index: resw (GRID_X+2)*(GRID_Y*2)
read_buff: resb BUFF_LIM