format ELF64 executable 3 include "lib/linux_syscall.inc" include "lib/itoa.inc" include "lib/print.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] call part_1 call part_2 ;; Unmap the mapped file munmap [input], [file_stat.st_size] ;; 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 input_fd dq -1 input dq -1 part_1_verbiage db 'Part 1: ' part_1_answer db ' ', 0 part_2_verbiage db 'Part 2: ' part_2_answer db ' ', 0 file_stat s_stat