114 lines
2.2 KiB
NASM
114 lines
2.2 KiB
NASM
format ELF64 executable 3
|
|
include "lib/linux_syscall.inc"
|
|
include "lib/itoa.inc"
|
|
include "lib/print.inc"
|
|
include "lib/file.inc"
|
|
|
|
segment readable executable
|
|
entry main
|
|
|
|
main:
|
|
mov rdi, input_filename
|
|
call load_file
|
|
|
|
call part_1
|
|
|
|
call part_2
|
|
|
|
call unload_file
|
|
|
|
;; Done!
|
|
exit 0
|
|
|
|
part_1:
|
|
;; Setup the loop variables for counting
|
|
;; rbx starts at the first byte of input, and is incremented to read it all
|
|
mov rbx, [input]
|
|
;; rcx tracks the current floor
|
|
mov rcx, 0
|
|
;; rdx counts down from the file's size to 0
|
|
mov rdx, [file_stat.st_size]
|
|
|
|
.lp:
|
|
;; Is the current character the "go up" character?
|
|
cmp byte [rbx], '('
|
|
;; If so, jump to "up"
|
|
je .up
|
|
;; Is the current character the "go down" character?
|
|
cmp byte [rbx], ')'
|
|
;; If so, it's the "go down" character, so decrement the current floor
|
|
je .down
|
|
;; Otherwise it's the EOF probably, skip it
|
|
jmp .other
|
|
.up:
|
|
;; We should "go up", so increment the current floor
|
|
inc rcx
|
|
jmp .other
|
|
.down:
|
|
;; We should "go down", so decrement the current floor
|
|
dec rcx
|
|
.other:
|
|
;; Check the next character in the file
|
|
inc rbx
|
|
;; Count down the file's length
|
|
dec rdx
|
|
;; If we haven't reached the end of the file, loop
|
|
jnz .lp
|
|
|
|
;; Put part 1's answer in rax
|
|
mov rax, rcx
|
|
|
|
;; Convert rax to a c string in rbx
|
|
mov rbx, part_1_answer
|
|
call itoa
|
|
|
|
;; Print part 1's verbiage
|
|
mov rdi, part_1_verbiage
|
|
call print_c_string
|
|
call print_newline
|
|
|
|
ret
|
|
|
|
part_2:
|
|
;; Setup the loop variables for counting
|
|
;; rbx starts at the first byte of input, and is incremented to read it all
|
|
mov rbx, [input]
|
|
;; rcx tracks the current floor
|
|
mov rcx, 0
|
|
;; rdx tracks how many steps we've made so far
|
|
mov rdx, 0
|
|
.lp:
|
|
cmp byte [rbx], '('
|
|
je .up
|
|
dec rcx
|
|
jmp .moved
|
|
.up:
|
|
inc rcx
|
|
.moved:
|
|
inc rdx
|
|
cmp rcx, 0
|
|
jl .done
|
|
inc rbx
|
|
jnz .lp
|
|
.done:
|
|
|
|
;; Put part 2's answer in rax
|
|
mov rax, rdx
|
|
|
|
;; Convert rax to a c string in rbx
|
|
mov rbx, part_2_answer
|
|
call itoa
|
|
|
|
;; Print part 2's verbiage
|
|
mov rdi, part_2_verbiage
|
|
call print_c_string
|
|
call print_newline
|
|
ret
|
|
|
|
segment readable writable
|
|
input_filename db '../data/2015/1/input.txt', 0
|
|
part_1_verbiage db 'Part 1: '
|
|
part_1_answer db ' ', 0
|
|
part_2_verbiage db 'Part 2: '
|
|
part_2_answer db ' ', 0
|