adventofcode2023/03/main_part1.s
2023-12-03 02:11:23 -06:00

180 lines
3.3 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*,
; adding numbers with sym neighbors to final_value
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
cmp byte [edx+1], '.'
je .r_nsym
jmp .has_sym_neighbor
.r_nsym:
; left
cmp byte [edx-1], '.'
je .l_nsym
jmp .has_sym_neighbor
.l_nsym:
; top
cmp byte [edx-(GRID_X+2)], '.'
je .t_nsym
jmp .has_sym_neighbor
.t_nsym:
; bottom
cmp byte [edx+(GRID_X+2)], '.'
je .b_nsym
jmp .has_sym_neighbor
.b_nsym:
; top left
cmp byte [edx-((GRID_X+2)+1)], '.'
je .tl_nsym
jmp .has_sym_neighbor
.tl_nsym:
; top right
cmp byte [edx-((GRID_X+2)-1)], '.'
je .tr_nsym
jmp .has_sym_neighbor
.tr_nsym:
; bottom left
cmp byte [edx+((GRID_X+2)-1)], '.'
je .bl_nsym
jmp .has_sym_neighbor
.bl_nsym:
; bottom right
cmp byte [edx+((GRID_X+2)+1)], '.'
je .br_nsym
jmp .has_sym_neighbor
.br_nsym:
; there's no symbol neighbor
; get next number
jmp .check_next_number
.has_sym_neighbor:
; we have a symbol neighbor!
; add to final value
mov edx, [numbers+eax*4]
add [final_value], edx
; 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