diff --git a/fasm/2015/1/problem.asm b/fasm/2015/1/problem.asm index eb35f24..bc02954 100644 --- a/fasm/2015/1/problem.asm +++ b/fasm/2015/1/problem.asm @@ -1,6 +1,7 @@ format ELF64 executable 3 include "lib/linux_syscall.inc" include "lib/itoa.inc" +include "lib/print.inc" segment readable executable entry main @@ -20,6 +21,17 @@ main: ;; 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] @@ -28,42 +40,47 @@ main: ;; rdx counts down from the file's size to 0 mov rdx, [file_stat.st_size] -lp: +.lp: ;; Is the current character the "go up" character? cmp byte [rbx], '(' ;; If so, jump to "up" - je 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 + je .down ;; Otherwise it's the EOF probably, skip it - jmp other -up: + jmp .other +.up: ;; We should "go up", so increment the current floor inc rcx - jmp other -down: + jmp .other +.down: ;; We should "go down", so decrement the current floor dec rcx -other: +.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 + jnz .lp ;; Put part 1's answer in rax mov rax, rcx - mov rbx, part_1 + + ;; Convert rax to a c string in rbx + mov rbx, part_1_answer call itoa - ;; Write part 1's verbiage to STDOUT - write STDOUT, part_1_verbiage, 8 - write STDOUT, part_1, 6 - write STDOUT, newline, 1 + ;; 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] @@ -71,44 +88,40 @@ other: mov rcx, 0 ;; rdx tracks how many steps we've made so far mov rdx, 0 -lp2: +.lp: cmp byte [rbx], '(' - je up2 + je .up dec rcx - jmp moved2 -up2: + jmp .moved +.up: inc rcx -moved2: +.moved: inc rdx cmp rcx, 0 - jl done + jl .done inc rbx - jnz lp2 -done: + jnz .lp +.done: ;; Put part 2's answer in rax mov rax, rdx - mov rbx, part_2 + + ;; Convert rax to a c string in rbx + mov rbx, part_2_answer 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 + ;; 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: ', 0 -part_1 db ' ', 0 -part_2_verbiage db 'Part 2: ', 0 -part_2 db ' ', 0 -newline db 10 +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 diff --git a/fasm/2015/2/problem.asm b/fasm/2015/2/problem.asm index 485ccbf..74dbd49 100644 --- a/fasm/2015/2/problem.asm +++ b/fasm/2015/2/problem.asm @@ -1,22 +1,28 @@ format ELF64 executable 3 include "lib/linux_syscall.inc" include "lib/print.inc" +include "lib/itoa.inc" segment readable executable entry main main: - mov rdi, input_filename + mov rax, 42069 + mov rbx, part_1 + call itoa + + mov rdi, part_1_verbiage call print_c_string + exit 0 segment readable writable input_filename db '../data/2015/1/input.txt', 0, 'more text', 0 input_fd dq -1 input dq -1 -part_1_verbiage db 'Part 1: ', 0 -part_1 db ' ', 0 +part_1_verbiage db 'Part 1: ' +part_1 db ' ', 0 part_2_verbiage db 'Part 2: ', 0 -part_2 db ' ', 0 +part_2 db ' ', 0 newline db 10 file_stat s_stat diff --git a/fasm/lib/itoa.inc b/fasm/lib/itoa.inc index bf25fb7..9eab9bf 100644 --- a/fasm/lib/itoa.inc +++ b/fasm/lib/itoa.inc @@ -1,12 +1,21 @@ ;; rax contains the integer ;; rbx contains a pointer to the string buffer itoa: + ;; Fill 6 digits with zeroes mov byte [rbx], '0' mov byte [rbx + 1], '0' mov byte [rbx + 2], '0' mov byte [rbx + 3], '0' mov byte [rbx + 4], '0' mov byte [rbx + 5], '0' + + ;; Special case for the number '0' + cmp rax, 0 + jne .not_zero + mov byte [rbx + 1], 0 + ret + +.not_zero: sub rax, 100000 inc byte [rbx] cmp rax, 0 @@ -42,4 +51,47 @@ itoa: add rax, 10 dec byte [rbx + 4] add [rbx + 5], rax + + + ;; Time to shift everything left + ;; End the current string with a null byte + mov byte [rbx + 6], 0 +.shift_left_loop: + cmp byte [rbx], '0' + jne .done + + mov rcx, rbx + inc rcx + mov rdx, [rcx] + and rdx, 255 + mov [rbx], dx + + inc rcx + mov rdx, [rcx] + and rdx, 255 + mov [rbx + 1], dx + + inc rcx + mov rdx, [rcx] + and rdx, 255 + mov [rbx + 2], dx + + inc rcx + mov rdx, [rcx] + and rdx, 255 + mov [rbx + 3], dx + + inc rcx + mov rdx, [rcx] + and rdx, 255 + mov [rbx + 4], dx + + inc rcx + mov rdx, [rcx] + and rdx, 255 + mov [rbx + 5], dx + + jmp .shift_left_loop + +.done: ret diff --git a/fasm/lib/print.inc b/fasm/lib/print.inc index fea16ee..a779072 100644 --- a/fasm/lib/print.inc +++ b/fasm/lib/print.inc @@ -31,3 +31,8 @@ print_c_string: write STDOUT, r11, r12 ret + +newline db 10, 0 +print_newline: + write STDOUT, newline, 1 + ret