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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
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
; TODO flag handling
; 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 final.stdin
.loop:
cmp r12, 2
jl final
mov r11, [rbp]
mov r11, [r11]
and r11, 0xff
cmp r11, 0x2d ;'-'
jne .cont
.cont:
add rbp, 8
sub r12, 1
jmp .loop
final:
; fix rbp and r12
mov rbp, rsp
mov r12, [rbp]
add rbp, 8 * 2 ; jump past 1st arg
.loop:
; if no more entries; exit
cmp r12, 2
jl exit
mov r10, [rbp]
cmp r10, 1
jl .cont
; arguments starting with "-" are special cases
mov r11, [rbp]
mov r11, [r11]
and r11, 0xff
cmp r11, 0x2d ;'-'
je .stdin
; 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
.cont:
add rbp, 8
sub r12, 1
jmp .loop
.stdin:
mov rax, 0
call process_fd
jmp .cont
usage:
; TODO: usage message
jmp errorexit
error:
;exit(1)
; TODO: process RAX to print meaningful message
errorexit:
mov rax, 60
mov rdi, 1
syscall
exit:
;exit(0)
mov rax, 60
mov rdi, 0
syscall
section .bss
bufSize: equ 65536
buf: resb bufSize
numbernonblankonly: equ 0b000001
showends: equ 0b000010
numberlines: equ 0b000100
squeezeblanks: equ 0b001000
showtabs: equ 0b010000
shownonprinting: equ 0b100000
|