format ELF64 executable 3 include "lib/linux_syscall.inc" include "lib/itoa.inc" segment readable executable entry main main: ;; Determine the file size of the input file stat input_filename, file_stat ;; Open a file descriptor for the input file open input_filename, 0 mov [input_fd], rax ;; Map the input file into memory mmap 0, [file_stat.st_size], PROT_READ, MAP_PRIVATE, [input_fd], 0 mov [input], rax ;; Close the input file close [input_fd] ;; 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 mov rbx, part_1 call itoa ;; Write part 1's verbiage to STDOUT write STDOUT, part_1_verbiage, 8 write STDOUT, part_1, 6 write STDOUT, newline, 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 tracks how many steps we've made so far mov rdx, 0 lp2: cmp byte [rbx], '(' je up2 dec rcx jmp moved2 up2: inc rcx moved2: inc rdx cmp rcx, 0 jl done inc rbx jnz lp2 done: ;; Put part 2's answer in rax mov rax, rdx mov rbx, part_2 call itoa ;; Write part 2's verbiage to STDOUT write STDOUT, part_2_verbiage, 8 write STDOUT, part_2, 6 write STDOUT, newline, 1 ;; Unmap the mapped file munmap [input], [file_stat.st_size] ;; Done! exit 0 segment readable writable input_filename db '../data/2015/1/input.txt', 0 input_fd dq -1 input dq -1 part_1_verbiage db 'Part 1: ', 0 part_1 db ' ', 0 part_2_verbiage db 'Part 2: ', 0 part_2 db ' ', 0 newline db 10 file_stat s_stat