180 lines
3.3 KiB
ArmAsm
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
|