1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
global _start
section .text
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
syscall
exit:
;exit(0)
mov rax, 60
mov rdi, 0
syscall
section .data
section .bss
bufSize: equ 65536
buf: resb bufSize
|