Playing around with arm assembly
- Assembly 95.4%
- Nix 4.6%
| .gitignore | ||
| cat.s | ||
| fibonacci.s | ||
| hello.s | ||
| README.md | ||
| shell.nix | ||
aarch64-hello
I'm programming a bunch of fun stuff in arm64 assembly without libc for funsies, currently included:
- A btoa
printnfunction for an arbitrary base between 2-64 - A decently optimised and extremely satisfying Fibonacci sequence
- A partial reimplementation of GNU
cat- Printing multiple files passed in as arguments
- Printing from a pipe when no arguments are provided
coreutils-compatible error handling- Tested against
coreutils - Not doing anything egregious...
- ...but not as optimised as I'd like
...I think I might know how to computer a bit haha
Example
$ as -o target/cat.o cat.s
$ ld -o target/cat target/cat.o
$ target/cat target/example cat.s
Printing my own cat's source with my own cat
Gosh I'm flexing so much today
.global _start
_start:
# Init return code
mov x19, #0
# Get filenames
ldr x20, [sp] // argc
add x21, sp, #16 // argv 8:name 16+:args
# For each arg (filename) run cat
for_arg:
cmp x20, #2
blo for_arg_end
ldr x0, [x21]
bl cat
sub x20, x20, #1
add x21, x21, #8
b for_arg
for_arg_end:
exit:
mov x0, x19
mov w8, #93
svc 0
.type handle_error, @function
handle_error:
mov x19, x0
mov x0, #2
ldr x1, =err_fallback
mov x2, #14
mov x8, #64
svc 0
ret
# x0 address of path string
.type cat, @function
cat:
# Get fd
mov x1, x0 // path
mov x0, #-100 // -100: Current directory
mov x2, #0 // read-only flag
mov x3, #0
mov x8, #56 // openat
svc 0
cmp x0, #0 // handle openat error
blt handle_error
mov x22, x0 // save fd
# Read and write
loop:
mov x0, x22 // fd
ldr x1, =buffer
mov x2, #64 // n bytes
mov x8, #63 // read
svc 0
cmp x0, #0 // exit loop on eof
beq loop_exit
cmp x0, #0 // handle read error
blt handle_error
mov x2, x0 // n bytes = n read bytes
mov x0, #1 // stdout
ldr x1, =buffer
mov x8, #64 // write
svc 0
cmp x0, #0 // handle read error
blt handle_error
b loop
loop_exit:
ret
.data
err_fallback: .ascii "cat: IO Error\n"
buffer: .byte 64