From 7cef5d23169eb8397065cacf22a22d4916df6450 Mon Sep 17 00:00:00 2001 From: Bill Rossi Date: Wed, 20 Dec 2023 07:16:28 -0500 Subject: [PATCH] Split my fasm code into reusable chunks --- fasm/2015/1/problem.asm | 187 +++---------------------------------- fasm/2015/2/problem.asm | 22 +++++ fasm/bin/run | 2 +- fasm/lib/itoa.inc | 45 +++++++++ fasm/lib/linux_syscall.inc | 72 ++++++++++++++ fasm/lib/macros.inc | 79 ++++++++++++++++ fasm/lib/print.inc | 33 +++++++ 7 files changed, 265 insertions(+), 175 deletions(-) create mode 100644 fasm/2015/2/problem.asm create mode 100644 fasm/lib/itoa.inc create mode 100644 fasm/lib/linux_syscall.inc create mode 100644 fasm/lib/macros.inc create mode 100644 fasm/lib/print.inc diff --git a/fasm/2015/1/problem.asm b/fasm/2015/1/problem.asm index 1148ce6..eb35f24 100644 --- a/fasm/2015/1/problem.asm +++ b/fasm/2015/1/problem.asm @@ -1,127 +1,6 @@ format ELF64 executable 3 - -struc s_stat -{ - .st_dev dq 0 - .st_ino dq 0 - .st_nlink dq 0 - .st_mode dd 0 - .st_uid dd 0 - .st_gid dq 0 - .st_rdev dq 0 - .st_size dq 0 - .st_blksize dq 0 - .st_blocks dq 0 - .st_atim dq 0 - .st_atim_nano dq 0 - .st_mtim dq 0 - .st_mtim_nano dq 0 - .st_ctim dq 0 - .st_ctim_nano dq 0 - .st_atim_idk dq 0 - .st_mtim_idk dq 0 - .st_ctim_idk dq 0 -} - -macro syscall1 nr, arg1 -{ - mov rax, nr - mov rdi, arg1 - syscall -} - -macro syscall2 nr, arg1, arg2 -{ - mov rax, nr - mov rdi, arg1 - mov rsi, arg2 - syscall -} - -macro syscall3 nr, arg1, arg2, arg3 -{ - mov rax, nr - mov rdi, arg1 - mov rsi, arg2 - mov rdx, arg3 - syscall -} - -macro syscall6 nr, arg1, arg2, arg3, arg4, arg5, arg6 -{ - mov rax, nr - mov rdi, arg1 - mov rsi, arg2 - mov rdx, arg3 - mov r10, arg4 - mov r8, arg5 - mov r9, arg6 - syscall -} - -STDOUT equ 1 -STDERR equ 2 - -SYS_read equ 0 -;; ssize_t read(int fd, void buf[.count], size_t count); -macro read fd,buf,count -{ - syscall3 SYS_read, fd, buf, count -} - -SYS_write equ 1 -;; ssize_t write(int fd, const void buf[.count], size_t count); -macro write fd,buf,count -{ - syscall3 SYS_write, fd, buf, count -} - -SYS_open equ 2 -;; int open(const char *pathname, int flags); -macro open pathname, flags -{ - syscall2 SYS_open, pathname, flags -} - -SYS_close equ 3 -;; int close(int fd); -macro close fd -{ - syscall1 SYS_close, fd -} - -SYS_stat equ 4 -;; int stat(const char *restrict pathname -;; struct stat *restrict statbuf); -macro stat pathname, statbuf -{ - syscall2 SYS_stat, pathname, statbuf -} - - -PROT_READ equ 1 -MAP_PRIVATE = 2 -SYS_mmap equ 9 -;; void *mmap(void addr[.length], size_t length, int prot, int flags, -;; int fd, off_t offset); -macro mmap addr, length, prot, flags, fd, offset -{ - syscall6 SYS_mmap, addr, length, prot, flags, fd, offset -} - -SYS_munmap equ 11 -;; int munmap(void addr[.length], size_t length); -macro munmap addr, length -{ - syscall2 SYS_munmap, addr, length -} - -SYS_exit equ 60 -;; [[noreturn]] void _exit(int status); -macro exit status -{ - syscall1 SYS_exit, status -} +include "lib/linux_syscall.inc" +include "lib/itoa.inc" segment readable executable entry main @@ -154,14 +33,20 @@ lp: cmp byte [rbx], '(' ;; If so, jump to "up" je up - ;; If not, it's the "go down" character, so decrement the current floor - dec rcx - ;; Skip over the "increment" - jmp moved + ;; 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 -moved: + 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 @@ -217,52 +102,6 @@ done: ;; Done! exit 0 -;; rax contains the integer -;; rbx contains a pointer to the string buffer -itoa: - mov byte [rbx], 48 - mov byte [rbx + 1], 48 - mov byte [rbx + 2], 48 - mov byte [rbx + 3], 48 - mov byte [rbx + 4], 48 - mov byte [rbx + 5], 48 - sub rax, 100000 - inc byte [rbx] - cmp rax, 0 - jge itoa - add rax, 100000 - dec byte [rbx] -.ten_thousand: - sub rax, 10000 - inc byte [rbx + 1] - cmp rax, 0 - jge .ten_thousand - add rax, 10000 - dec byte [rbx + 1] -.one_thousand: - sub rax, 1000 - inc byte [rbx + 2] - cmp rax, 0 - jge .one_thousand - add rax, 1000 - dec byte [rbx + 2] -.one_hundred: - sub rax, 100 - inc byte [rbx + 3] - cmp rax, 0 - jge .one_hundred - add rax, 100 - dec byte [rbx + 3] -.ten: - sub rax, 10 - inc byte [rbx + 4] - cmp rax, 0 - jge .ten - add rax, 10 - dec byte [rbx + 4] - add [rbx + 5], rax - ret - segment readable writable input_filename db '../data/2015/1/input.txt', 0 input_fd dq -1 diff --git a/fasm/2015/2/problem.asm b/fasm/2015/2/problem.asm new file mode 100644 index 0000000..485ccbf --- /dev/null +++ b/fasm/2015/2/problem.asm @@ -0,0 +1,22 @@ +format ELF64 executable 3 +include "lib/linux_syscall.inc" +include "lib/print.inc" + +segment readable executable +entry main + +main: + mov rdi, input_filename + 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_2_verbiage db 'Part 2: ', 0 +part_2 db ' ', 0 +newline db 10 +file_stat s_stat diff --git a/fasm/bin/run b/fasm/bin/run index 60303cd..584fb3f 100755 --- a/fasm/bin/run +++ b/fasm/bin/run @@ -3,4 +3,4 @@ year=$1 day=$2 -bin/fasm $year/$day/problem.asm $year/$day/problem && time ./$year/$day/problem \ No newline at end of file +bin/fasm $year/$day/problem.asm $year/$day/problem && time ./$year/$day/problem diff --git a/fasm/lib/itoa.inc b/fasm/lib/itoa.inc new file mode 100644 index 0000000..bf25fb7 --- /dev/null +++ b/fasm/lib/itoa.inc @@ -0,0 +1,45 @@ +;; rax contains the integer +;; rbx contains a pointer to the string buffer +itoa: + 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' + sub rax, 100000 + inc byte [rbx] + cmp rax, 0 + jge itoa + add rax, 100000 + dec byte [rbx] +.ten_thousand: + sub rax, 10000 + inc byte [rbx + 1] + cmp rax, 0 + jge .ten_thousand + add rax, 10000 + dec byte [rbx + 1] +.one_thousand: + sub rax, 1000 + inc byte [rbx + 2] + cmp rax, 0 + jge .one_thousand + add rax, 1000 + dec byte [rbx + 2] +.one_hundred: + sub rax, 100 + inc byte [rbx + 3] + cmp rax, 0 + jge .one_hundred + add rax, 100 + dec byte [rbx + 3] +.ten: + sub rax, 10 + inc byte [rbx + 4] + cmp rax, 0 + jge .ten + add rax, 10 + dec byte [rbx + 4] + add [rbx + 5], rax + ret diff --git a/fasm/lib/linux_syscall.inc b/fasm/lib/linux_syscall.inc new file mode 100644 index 0000000..1b898c8 --- /dev/null +++ b/fasm/lib/linux_syscall.inc @@ -0,0 +1,72 @@ +include "macros.inc" + +STDOUT equ 1 +STDERR equ 2 + +SYS_read equ 0 +;; ssize_t read(int fd, void buf[.count], size_t count); +macro read fd,buf,count +{ + syscall3 SYS_read, fd, buf, count +} + +SYS_write equ 1 +;; ssize_t write(int fd, const void buf[.count], size_t count); +macro write fd,buf,count +{ + syscall3 SYS_write, fd, buf, count +} + +SYS_open equ 2 +;; int open(const char *pathname, int flags); +macro open pathname, flags +{ + syscall2 SYS_open, pathname, flags +} + +SYS_close equ 3 +;; int close(int fd); +macro close fd +{ + syscall1 SYS_close, fd +} + +SYS_stat equ 4 +;; int stat(const char *restrict pathname +;; struct stat *restrict statbuf); +macro stat pathname, statbuf +{ + syscall2 SYS_stat, pathname, statbuf +} + + +PROT_READ equ 1 +MAP_PRIVATE = 2 +SYS_mmap equ 9 +;; void *mmap(void addr[.length], size_t length, int prot, int flags, +;; int fd, off_t offset); +macro mmap addr, length, prot, flags, fd, offset +{ + syscall6 SYS_mmap, addr, length, prot, flags, fd, offset +} + +SYS_munmap equ 11 +;; int munmap(void addr[.length], size_t length); +macro munmap addr, length +{ + syscall2 SYS_munmap, addr, length +} + +SYS_alarm equ 37 +;; unsigned int alarm(unsigned int seconds); +macro alarm seconds +{ + syscall1 SYS_alarm, seconds +} + +SYS_exit equ 60 +;; [[noreturn]] void _exit(int status); +macro exit status +{ + syscall1 SYS_exit, status +} \ No newline at end of file diff --git a/fasm/lib/macros.inc b/fasm/lib/macros.inc new file mode 100644 index 0000000..20354cb --- /dev/null +++ b/fasm/lib/macros.inc @@ -0,0 +1,79 @@ +struc s_stat +{ + .st_dev dq 0 + .st_ino dq 0 + .st_nlink dq 0 + .st_mode dd 0 + .st_uid dd 0 + .st_gid dq 0 + .st_rdev dq 0 + .st_size dq 0 + .st_blksize dq 0 + .st_blocks dq 0 + .st_atim dq 0 + .st_atim_nano dq 0 + .st_mtim dq 0 + .st_mtim_nano dq 0 + .st_ctim dq 0 + .st_ctim_nano dq 0 + .st_atim_idk dq 0 + .st_mtim_idk dq 0 + .st_ctim_idk dq 0 +} + +macro syscall1 nr, arg1 +{ + mov rax, nr + mov rdi, arg1 + syscall +} + +macro syscall2 nr, arg1, arg2 +{ + mov rax, nr + mov rdi, arg1 + mov rsi, arg2 + syscall +} + +macro syscall3 nr, arg1, arg2, arg3 +{ + mov rax, nr + mov rdi, arg1 + mov rsi, arg2 + mov rdx, arg3 + syscall +} + +macro syscall4 nr, arg1, arg2, arg3, arg4 +{ + mov rax, nr + mov rdi, arg1 + mov rsi, arg2 + mov rdx, arg3 + mov r10, arg4 + syscall +} + +macro syscall5 nr, arg1, arg2, arg3, arg4, arg5 +{ + mov rax, nr + mov rdi, arg1 + mov rsi, arg2 + mov rdx, arg3 + mov r10, arg4 + mov r8, arg5 + syscall +} + +macro syscall6 nr, arg1, arg2, arg3, arg4, arg5, arg6 +{ + mov rax, nr + mov rdi, arg1 + mov rsi, arg2 + mov rdx, arg3 + mov r10, arg4 + mov r8, arg5 + mov r9, arg6 + syscall +} diff --git a/fasm/lib/print.inc b/fasm/lib/print.inc new file mode 100644 index 0000000..fea16ee --- /dev/null +++ b/fasm/lib/print.inc @@ -0,0 +1,33 @@ +include "linux_syscall.inc" + +;; rdi contains the address of the null-terminated string to print to STDOUT +print_c_string: + ;; initialize counter + mov rax, 0 + + ;; initialize character pointer + mov rbx, rdi + +.loop: + ;; Is the current character \0? + cmp byte [rbx], 0 + + ;; If so we can print + je .print + + ;; Otherwise, increment the counter and check the next character + inc rax + inc rbx + jmp .loop + +.print: + ;; rdi is the start point of the string to print + mov r11, rdi + + ;; rdx contains the number of characters to print + mov r12, rax + + ;; Write to STDOUT + write STDOUT, r11, r12 + + ret