adventofcode2023/12/main.s
2023-12-12 09:36:26 -06:00

172 lines
3.1 KiB
ArmAsm

global _start
[bits 32]
[section .text]
%include "utils.s"
_start:
mov esi, file
parse_line:
; find first num
mov ebp, esi ; line start
.first_num:
mov edi, esi ; save before loc
call dec_parse
jc .first_num
; edi has pointer to just before numbers
mov ecx, edi
sub ecx, ebp
dec ecx ; space
xchg esi, ebp
mov [line_len], ecx
mov edi, line
rep movsb
xchg esi, ebp
mov dword [contiguous_broken+ 0], 0
mov dword [contiguous_broken+ 4], 0
mov dword [contiguous_broken+ 8], 0
mov dword [contiguous_broken+12], 0
mov dword [contiguous_broken+16], 0
mov dword [contiguous_broken+20], 0
mov dword [contiguous_broken+24], 0
mov dword [contiguous_broken+28], 0
mov dword [contiguous_broken+32], 0
mov dword [contiguous_broken+36], 0
mov dword [contiguous_broken+40], 0
mov dword [contiguous_broken+44], 0
mov dword [contiguous_broken+48], 0
mov dword [contiguous_broken+52], 0
mov dword [contiguous_broken+56], 0
mov dword [contiguous_broken+60], 0
mov edi, contiguous_broken
stosb
.next_num:
cmp byte [esi-1], 10 ; \n
je .newline
call dec_parse
jc .next_num
.got_num:
stosb
jmp .next_num
.newline:
push esi ; save input line
; clear cache
mov edi, cache
mov ecx, (cache.end - cache)/4
mov eax, -1
rep stosd
; setup do_stream vars
xor esi, esi ; line idx
mov ebp, [line_len]
xor edi, edi ; contiguous_broken idx
xor edx, edx ; poss_counter high
xor ebx, ebx ; poss_counter low
call do_stream ; call into recursive routine
add [final_value+0], ebx ; poss_counter low
adc [final_value+4], edx ; poss_counter high
mov eax, edx
call print_dec
call space
mov eax, ebx
call print_dec
call newline
jmp parse_line_cont
do_stream:
cmp byte [line+esi], '.'
je .cont
cmp byte [line+esi], '#'
jne .branch
.broke:
cmp byte [contiguous_broken+edi], 0
je .ret ; branch impossible
movzx ecx, byte [contiguous_broken+edi]
inc edi
.consume_things:
mov al, byte [line+esi]
inc esi
cmp esi, ebp
ja .ret ; branch impossible
cmp al, '.'
je .ret ; branch impossible
loop .consume_things
cmp esi, ebp
je .cont
cmp byte [line+esi], '#'
je .ret ; branch impossible
; .cont consumes . or ? (must be .)
jmp .cont
.branch: ; recursive branch
mov eax, esi
shl eax, 8 ; *256
cmp dword [eax+edi*8+cache], -1
je .not_cached
add ebx, [eax+edi*8+(cache+0)]
adc edx, [eax+edi*8+(cache+4)]
jmp .cont
.not_cached:
push edx
push ebx
push esi
push edi
xor ebx, ebx
xor edx, edx
call do_stream.broke ; assume #
pop edi
pop esi
mov eax, esi
shl eax, 8
mov [eax+edi*8+(cache+0)], ebx
mov [eax+edi*8+(cache+4)], edx
pop eax
add ebx, eax
pop eax
adc edx, eax
; assume .
.cont:
inc esi
cmp esi, ebp
jb do_stream
; iff we are at the end of stream
; and contiguous_broken is exhausted
; we add a possibility
cmp byte [contiguous_broken+edi], 0
jne .ret
add ebx, 1 ; poss counter
adc edx, 0
.ret:
ret
parse_line_cont:
pop esi
cmp esi, file.over-1
jb parse_line
call newline
game_over:
mov eax, [final_value+4]
call print_dec
call space
mov eax, [final_value+0]
call print_dec
call newline
jmp exit
[section .data]
line_len: dd 0
final_value: dd 0, 0
final_setting: dd 0, 0
curr_setting: dd 0, 0
file: incbin "input5"
.over:
nl_str: db "new line!"
.over:
[section .bss]
contiguous_broken: resb 64
line: resb 512
cache: resd 256*64*2
cache.end: