From 47c1398c6dd8d32801a250450eeccbce47eb5ba7 Mon Sep 17 00:00:00 2001
From: Bill Rossi <bassguitarbill@gmail.com>
Date: Thu, 21 Dec 2023 09:40:11 -0500
Subject: [PATCH] Assembly code is really fun

---
 fasm/2015/1/problem.asm | 89 +++++++++++++++++++++++------------------
 fasm/2015/2/problem.asm | 14 +++++--
 fasm/lib/itoa.inc       | 52 ++++++++++++++++++++++++
 fasm/lib/print.inc      |  5 +++
 4 files changed, 118 insertions(+), 42 deletions(-)

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