172 lines
3.1 KiB
ArmAsm
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:
|