Split my fasm code into reusable chunks

This commit is contained in:
Bill Rossi 2023-12-20 07:16:28 -05:00
parent b7daaa989f
commit 7cef5d2316
7 changed files with 265 additions and 175 deletions

View File

@ -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

22
fasm/2015/2/problem.asm Normal file
View File

@ -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

View File

@ -3,4 +3,4 @@
year=$1
day=$2
bin/fasm $year/$day/problem.asm $year/$day/problem && time ./$year/$day/problem
bin/fasm $year/$day/problem.asm $year/$day/problem && time ./$year/$day/problem

45
fasm/lib/itoa.inc Normal file
View File

@ -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

View File

@ -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
}

79
fasm/lib/macros.inc Normal file
View File

@ -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
}

33
fasm/lib/print.inc Normal file
View File

@ -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