adventofcode2023/11/main.s
2023-12-11 03:28:34 -06:00

279 lines
3.7 KiB
ArmAsm

%define EXPANSION 1000000-1
global _start
[bits 32]
[section .text]
%include "utils.s"
_start:
; find line length
mov edi, file
mov ecx, file.over - file
mov al, 10 ; \n
repne scasb
mov eax, edi
sub eax, file
mov [line_len], eax
call print_dec
call newline
mov eax, -1
mov ecx, 512
mov edi, empty_rows
rep stosd
mov eax, -1
mov ecx, 512*2
mov edi, stars
rep stosd
; find empty rows
xor ebx, ebx
mov ebp, empty_rows
check_rows:
mov eax, [line_len]
mov ecx, eax
mul ebx
lea edi, [eax+file]
mov esi, edi
add esi, ecx
mov al, '.'
repe scasb
mov eax, esi
cmp edi, esi
jne .not_empty
.empty:
mov [ebp], ebx
add ebp, 4
.not_empty:
.cont:
inc ebx
cmp eax, file.over
jb check_rows
; find empty cols
xor ebx, ebx
mov ebp, empty_cols
check_cols:
lea edi, [file+ebx]
.l:
cmp edi, file.over
jae .empty
cmp byte [edi], '.'
jne .not_empty
add edi, [line_len]
jmp .l
.empty:
mov [ebp], ebx
add ebp, 4
.not_empty:
inc ebx
cmp ebx, [line_len]
jb check_cols
print_empty_rows:
mov esi, empty_str
mov ecx, 6
call print_string
mov esi, empty_rows
xor eax, eax
.l:
lodsd
cmp eax, -1
je .done
call space
call print_dec
jmp .l
.done:
call newline
print_empty_cols:
mov esi, empty_str
mov ecx, 6
call print_string
mov esi, empty_cols
xor eax, eax
.l:
lodsd
cmp eax, -1
je .done
call space
call print_dec
jmp .l
.done:
call newline
; find #s
xor ebx, ebx ; row
mov ebp, stars
find_stars:
mov eax, ebx
mul dword [line_len]
lea edi, [file+eax] ; row ptr
cmp edi, file.over
jae .done
xor ecx, ecx ; col
.for_cols:
cmp byte [edi+ecx], '#'
jne .for_cols_cont
mov eax, ebx
call print_dec
call space
mov [ebp], ebx ; row
mov eax, ecx
call print_dec
call newline
mov [ebp+4], ecx ; col
add ebp, 8
.for_cols_cont:
inc ecx
cmp ecx, [line_len]
jb .for_cols
inc ebx
jmp find_stars
.done:
call newline
; calc adjustments
calc_adj:
xor ecx, ecx
.fill:
mov [adj_rows+ecx*4], ecx
mov [adj_cols+ecx*4], ecx
inc ecx
cmp ecx, 256
jb .fill
; do rows
mov esi, empty_rows
.rows:
lodsd
cmp eax, -1
je .rows_done
inc eax
.add_to_rows:
add dword [adj_rows+eax*4], EXPANSION
inc eax
cmp eax, 256
jb .add_to_rows
jmp .rows
.rows_done:
; do cols
mov esi, empty_cols
.cols:
lodsd
cmp eax, -1
je .cols_done
inc eax
.add_to_cols:
add dword [adj_cols+eax*4], EXPANSION
inc eax
cmp eax, 256
jb .add_to_cols
jmp .cols
.cols_done:
; apply adjustments
apply_adj:
xor eax, eax
mov esi, stars
mov edi, stars
.l:
lodsd ; row
cmp eax, -1
je .done
mov eax, [adj_rows+eax*4]
stosd
lodsd ; col
mov eax, [adj_cols+eax*4]
stosd
jmp .l
.done:
; print stars
print_stars:
mov esi, stars
xor eax, eax
.l:
lodsd
cmp eax, -1
je .done
call print_dec
call space
lodsd
call print_dec
call newline
jmp .l
.done:
call newline
; calc distances
sub esp, 4
mov ebp, stars
calc_dist:
lea esi, [ebp+8]
mov ecx, [ebp] ; row
mov edx, [ebp+4] ; col
mov [esp], ebp
xor edi, edi ; running sum low
xor ebp, ebp ; running sum high
.to_next:
lodsd ; row
cmp eax, -1
je .all_added
sub eax, ecx
; abs (m := n>>31, n := (n+m)^m)
mov ebx, eax
sar ebx, 31
add eax, ebx
xor eax, ebx
; add to total
add edi, eax
adc ebp, 0
lodsd ; col
sub eax, edx
mov ebx, eax
sar ebx, 31
add eax, ebx
xor eax, ebx
; add to total
add edi, eax
adc ebp, 0
jmp .to_next
.all_added:
add dword [final_value], edi
adc dword [final_value_high], ebp
calc_dist_cont:
mov ebp, [esp]
add ebp, 8
cmp dword [ebp], -1
jne calc_dist
calc_dist_end:
add esp, 4
game_over:
; answer is penultimate + (ultimate * 2^32)
mov eax, [final_value]
call print_dec
call newline
mov eax, [final_value_high]
call print_dec
call newline
jmp exit
[section .data]
line_len: dd 0
final_value: dd 0
final_value_high: dd 0
file: incbin "input"
.over:
empty_str: db "Empty:"
not_empty_str: db "Not Empty:"
[section .bss]
empty_rows: resd 256
empty_cols: resd 256
adj_rows: resd 256
adj_cols: resd 256
stars: resd 512*2