aboutsummaryrefslogtreecommitdiffstats
path: root/cat.s
diff options
context:
space:
mode:
Diffstat (limited to 'cat.s')
-rw-r--r--cat.s97
1 files changed, 92 insertions, 5 deletions
diff --git a/cat.s b/cat.s
index 79d9f30..8a047e7 100644
--- a/cat.s
+++ b/cat.s
@@ -1,16 +1,103 @@
global _start
section .text
-_start:
+process_fd:
+ ; rax = fd
+
+ ; read(rax, buf, bufSize)
+ mov rbx, rax
+ mov rdi, rax
+ mov rsi, buf
+ mov rdx, bufSize
+ mov rax, 0
+ syscall
+
+ ; check if stuff was read
+ cmp rax, 1
+ jl .ret
+
+ ; write(1, buf, rax)
+ mov rdi, 1
+ mov rsi, buf
+ mov rdx, rax
mov rax, 1
+ syscall
+
+ ; continue loop
+ mov rax, rbx
+ jmp process_fd
+.ret:
+ ; return rax
+ mov rax, rbx
+ ret
+
+_start:
+ ; r12 = argc
+ mov rbp, rsp
+ mov r12, [rbp]
+ cmp r12, 2
+ jl .stdin
+
+ add rbp, 8 * 2 ; jump past 1st arg
+
+.loop:
+ ; if no more entries; exit
+ cmp r12, 2
+ jl exit
+
+ ; arguments starting with "-" are special cases
+ mov r13, [rbp]
+ cmp r13, 0x2d ;'-'
+ je .special
+
+ ; open(rbp, 0, 0)
+ mov rax, 2
+ mov rdi, [rbp]
+ mov rsi, 0
+ mov rdx, 0
+ syscall
+
+ ; make sure fd exists
+ cmp rax, 1
+ jl .error
+ ; print file
+ call process_fd
+ ; returns input
+ ; close(rax)
+ mov rdi, rax
+ mov rax, 3
+ syscall
+
+ ; prepare registers for next loop
+ add rbp, 8
+ sub r12, 1
+ jmp .loop
+
+ ; unreachable. insurance
+ jmp exit
+
+.special:
+ ;special case handler (TODO)
+ ; stdin passthrough
+.stdin:
+ mov rax, 0
+ call process_fd
+ jmp .loop
+
+.error:
+ ;exit(1)
+ ; TODO: process RAX to print meaningful message
+ mov rax, 60
mov rdi, 1
- mov rsi, msg
- mov rdx, msgSize
syscall
+exit:
+ ;exit(0)
mov rax, 60
mov rdi, 0
syscall
section .data
-msg: db "Hello, world!", 10
-msgSize: EQU $ - msg
+
+ section .bss
+bufSize: equ 65536
+buf: resb bufSize