day 13 part 1&2

This commit is contained in:
Lucia Ceionia 2023-12-13 04:17:13 -06:00
parent 400b90c50e
commit 900602889b
6 changed files with 1933 additions and 0 deletions

3
13/Makefile Normal file
View File

@ -0,0 +1,3 @@
all:
nasm -g -felf32 main.s && ld -melf_i386 -g main.o

1351
13/input Normal file

File diff suppressed because it is too large Load Diff

17
13/input_test Normal file
View File

@ -0,0 +1,17 @@
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#.##..##.
..#.##.#.
##......#
##......#
..#.##.#.
..##..##.
#.#.##.#.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#...##..#
#....#..#
..##..###
#####.##.
#####.##.
..##..###
#....#..#
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!@

159
13/main.s Normal file
View File

@ -0,0 +1,159 @@
global _start
[bits 32]
[section .text]
%include "utils.s"
_start:
mov dword [start], file
jmp do_line_cont
do_line:
; line len
mov esi, edi ; start
mov ecx, 1024
mov al, 10 ; \n
repne scasb
mov eax, edi
sub eax, esi
mov [line_len], eax
mov [start], esi
jmp vert_loop
do_line_cont:
; get next input
mov al, '!'
mov ecx, 1024
mov edi, [start]
repne scasb
mov ecx, 1024
repe scasb
cmp byte [edi-1], '@'
je game_over
.skip_newline:
cmp byte [edi], 10
jne do_line
inc edi
jmp .skip_newline
vert_loop:
mov ebp, [line_len]
mov edx, 1 ; col num
mov esi, [start] ; first col
.check_cols:
cmp byte [esi+1], 10 ; \n
je .done
lea edi, [esi+1]
push esi
xor ecx, ecx ; wrong thing count
jmp .check_rows
.cont:
pop esi
inc esi
inc edx
jmp .check_cols
.potential_mirror:
inc edi
dec esi
cmp byte [edi], 10
je .mirror
cmp byte [esi], 10
je .mirror
; esi left col edi right col
.check_rows:
xor eax, eax ; row 0
.check_rows_l:
mov bl, [esi+eax]
mov bh, [edi+eax]
cmp bl, '!'
je .potential_mirror
cmp bh, bl
je .eq
inc cl
cmp cl, 2
je .cont
.eq:
add eax, ebp
jmp .check_rows_l
.mirror:
cmp cl, 0 ; we want *exactly* one wrong
je .cont
mov eax, edx
call print_dec
call newline
add [final_value], eax
add esp, 4
jmp do_line_cont
.done:
horz_loop:
mov ebp, [line_len]
mov edx, 1 ; col num
mov esi, [start] ; first row
.check_rows:
cmp byte [esi+ebp], '!'
je .done
lea edi, [esi+ebp]
push esi
xor ecx, ecx ; wrong thing count
jmp .check_cols
.cont:
pop esi
add esi, ebp
inc edx
jmp .check_rows
.potential_mirror:
add edi, ebp
sub esi, ebp
cmp byte [edi], '!'
je .mirror
cmp byte [esi], '!'
je .mirror
; esi up row edi down row
.check_cols:
xor eax, eax ; row 0
.check_cols_l:
mov bl, [esi+eax]
mov bh, [edi+eax]
cmp bl, 10
je .potential_mirror
cmp bh, bl
je .eq
inc cl
cmp cl, 2
je .cont
.eq:
inc eax
jmp .check_cols_l
.mirror:
cmp cl, 0 ; we want *exactly* one wrong
je .cont
mov eax, edx
call space
call print_dec
call newline
mov ebx, 100
mul ebx
add [final_value], eax
add esp, 4
.done:
jmp do_line_cont
game_over:
call newline
call newline
mov eax, [final_value]
call print_dec
call newline
jmp exit
[section .data]
final_value: dd 0
start: dd 0
line_len: dd 0
file: incbin "input"
.over:
[section .bss]

145
13/main_part1.s Normal file
View File

@ -0,0 +1,145 @@
global _start
[bits 32]
[section .text]
%include "utils.s"
_start:
mov dword [start], file
jmp do_line_cont
do_line:
; line len
mov esi, edi ; start
mov ecx, 1024
mov al, 10 ; \n
repne scasb
mov eax, edi
sub eax, esi
mov [line_len], eax
mov [start], esi
jmp vert_loop
do_line_cont:
; get next input
mov al, '!'
mov ecx, 1024
mov edi, [start]
repne scasb
mov ecx, 1024
repe scasb
cmp byte [edi-1], '@'
je game_over
.skip_newline:
cmp byte [edi], 10
jne do_line
inc edi
jmp .skip_newline
vert_loop:
mov ebp, [line_len]
mov edx, 1 ; col num
mov esi, [start] ; first col
.check_cols:
cmp byte [esi+1], 10 ; \n
je .done
lea edi, [esi+1]
push esi
jmp .check_rows
.cont:
pop esi
inc esi
inc edx
jmp .check_cols
.potential_mirror:
inc edi
dec esi
cmp byte [edi], 10
je .mirror
cmp byte [esi], 10
je .mirror
; esi left col edi right col
.check_rows:
xor eax, eax ; row 0
.check_rows_l:
mov bl, [esi+eax]
mov bh, [edi+eax]
cmp bl, '!'
je .potential_mirror
cmp bh, bl
jne .cont
add eax, ebp
jmp .check_rows_l
.mirror:
mov eax, edx
call print_dec
call newline
add [final_value], eax
add esp, 4
jmp do_line_cont
.done:
horz_loop:
mov ebp, [line_len]
mov edx, 1 ; col num
mov esi, [start] ; first row
.check_rows:
cmp byte [esi+ebp], '!'
je .done
lea edi, [esi+ebp]
push esi
jmp .check_cols
.cont:
pop esi
add esi, ebp
inc edx
jmp .check_rows
.potential_mirror:
add edi, ebp
sub esi, ebp
cmp byte [edi], '!'
je .mirror
cmp byte [esi], '!'
je .mirror
; esi up row edi down row
.check_cols:
xor eax, eax ; row 0
.check_cols_l:
mov bl, [esi+eax]
mov bh, [edi+eax]
cmp bl, 10
je .potential_mirror
cmp bh, bl
jne .cont
inc eax
jmp .check_cols_l
.mirror:
mov eax, edx
call space
call print_dec
call newline
mov ebx, 100
mul ebx
add [final_value], eax
add esp, 4
.done:
jmp do_line_cont
game_over:
call newline
call newline
mov eax, [final_value]
call print_dec
call newline
jmp exit
[section .data]
final_value: dd 0
start: dd 0
line_len: dd 0
file: incbin "input"
.over:
[section .bss]

258
13/utils.s Normal file
View File

@ -0,0 +1,258 @@
; call # val val2
; int $0x80 eax eax edx -
;
; arg1 arg2 arg3 arg4 arg5 arg6 arg7
; ebx ecx edx esi edi ebp -
exit:
mov eax, 1 ; exit
int 0x80
; filename in EBX
; return handle in EBX
; read only
open_file:
push eax
push ecx
mov eax, 5 ; open
xor ecx, ecx ; read only
int 0x80
mov ebx, eax
pop ecx
pop eax
ret
; file handle in EBX
; buffer in ECX
; count of bytes to read in EDX
; return bytes actually read in EAX
; exits on error
read_file:
mov eax, 3 ; read
int 0x80
test eax, eax
js .err
ret
.err:
mov eax, 4 ; write
mov ebx, 1 ; stdout
mov ecx, .err_str
mov edx, 21
int 0x80
jmp exit
.err_str: db `Could not read file.\n`
; string input in ESI
; value in EAX
; CF set if none, clear if some
; ESI set past checked area
dec_parse:
push ebx
push edx
push edi
xor eax, eax
xor edi, edi
mov ebx, 10 ; base
lodsb
sub al, '0'
js .no_input
cmp al, 9
jle .got_char
.no_input:
stc ; set CF
jmp .done
.loop:
xor eax,eax
lodsb
sub al, '0'
js .dec_done
cmp al, 9
jg .dec_done
.got_char:
xchg edi,eax
mul ebx
add edi,eax
jmp .loop
.dec_done:
clc ; clear CF
.done:
mov eax,edi
pop edi
pop edx
pop ebx
ret
; string input in ESI
; value in EAX
; CF set if none, clear if some
; ESI set past checked area
sign_dec_parse:
push ebx
push ecx
push edx
push edi
xor eax, eax
xor edi, edi
xor ecx, ecx ; neg flag
mov ebx, 10 ; base
cmp byte [esi], '-'
jne .no_minus
inc esi
mov cl, 1
.no_minus:
lodsb
sub al, '0'
js .no_input
cmp al, 9
jle .got_char
.no_input:
stc ; set CF
jmp .done
.loop:
xor eax,eax
lodsb
sub al, '0'
js .dec_done
cmp al, 9
jg .dec_done
.got_char:
xchg edi,eax
mul ebx
add edi,eax
jmp .loop
.dec_done:
test ecx, ecx
jz .not_neg
neg edi
.not_neg:
clc ; clear CF
.done:
mov eax,edi
pop edi
pop edx
pop ecx
pop ebx
ret
; modifies no regs
newline:
pushad
push 10
mov eax, 4 ; write
mov ebx, 1 ; stdout
mov ecx, esp ; string
mov edx, 1 ; length
int 0x80
add esp, 4
popad
ret
; modifies no regs
space:
pushad
push 9
mov eax, 4 ; write
mov ebx, 1 ; stdout
mov ecx, esp ; string
mov edx, 1 ; length
int 0x80
add esp, 4
popad
ret
; input in EAX, all regs unmodified
print_dec:
pushad ; save regs
; max 4294967296 is 10 chars
; round to nearest 32-bit boundary
sub esp, 12
; string in ECX, length in EDX
lea ecx, [esp+11] ; last possible byte
; check for 0
test eax, eax
jz .zero
mov ebx, 10 ; base 10
xor esi, esi ; counter
.div_shit:
xor edx, edx
; divide
div ebx
dec ecx ; next char
inc esi
; store
add dl, '0'
mov byte [ecx], dl
; check if done
test eax, eax
jnz .div_shit ; continue
mov edx, esi ; counter in edx
jmp .write
.zero:
mov byte [ecx], '0'
mov edx, 1 ; length
.write:
mov eax, 4 ; write
mov ebx, 1 ; stdout
int 0x80
add esp, 12 ; restore stack
popad ; restore regs
ret
; input in EAX, all regs unmodified
print_sign_dec:
pushad ; save regs
; range -2147483648 to 2147483647 is 11 chars
; round to nearest 32-bit boundary
sub esp, 12
; string in ECX, length in EDX
lea ecx, [esp+11] ; last possible byte
; check for 0, negative
xor ebp, ebp
test eax, eax
jz .zero
jns .positive
neg eax
mov ebp, 1
.positive:
mov ebx, 10 ; base 10
xor esi, esi ; counter
.div_shit:
xor edx, edx
; divide
div ebx
dec ecx ; next char
inc esi
; store
add dl, '0'
mov byte [ecx], dl
; check if done
test eax, eax
jnz .div_shit ; continue
mov edx, esi ; counter in edx
jmp .write
.zero:
mov byte [ecx], '0'
mov edx, 1 ; length
.write:
test ebp, ebp
jz .no_minus
dec ecx
inc edx
mov byte [ecx], '-'
.no_minus:
mov eax, 4 ; write
mov ebx, 1 ; stdout
int 0x80
add esp, 12 ; restore stack
popad ; restore regs
ret
; input in ESI, len in ECX, all regs unmodified
print_string:
pushad ; save regs
mov eax, 4 ; write
mov ebx, 1 ; stdout
mov edx, ecx ; length
mov ecx, esi ; string
int 0x80
popad ; restore regs
ret