-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathsyscall.asm
185 lines (138 loc) · 2.25 KB
/
syscall.asm
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
%include "print.mac"
%include "syscall_int.mac"
%define READ 0
%define WRITE 1
%define POLL 7
%define IOCTL 16
%define NANOSLEEP 35
%define EXIT 60
%macro SYS 1
mov rax, %1
syscall
test rax, rax
js syscall_err
%endmacro
section .data
sleep_tv:
.sec dq 0
.usec dq 0
section .text
global sleep
; rax: seconds
; rdx: nanoseconds
sleep:
push rdi
push rsi
mov qword [sleep_tv.sec], rax
mov qword [sleep_tv.usec], rdx
mov rdi, sleep_tv ; timespec struct
mov rsi, 0 ; don't store remaining time
SYS NANOSLEEP
pop rsi
pop rdi
ret
global ioctl
%define TCGETS 21505 ; attr to get struct
%define TCPUTS 21506 ; attr to put struct
; rax - termios struct pointer
; rdx - 0: get, 1: put
ioctl:
push rdi
push rsi
add rdx, TCGETS
mov rsi, rdx
mov rdx, rax
mov rdi, 0
SYS IOCTL
pop rsi
pop rdi
ret
global exit
; rax: exit code
exit:
mov rdi, rax
mov rax, EXIT
syscall
; this part must never execute,
; but still...
ret
section .data
; poll function struct arg
poll_fd:
dd STDIN ; fd
dw 1 ; events
dw 0 ; revents
section .text
global poll
; rax: buffer
; rdx; count
poll:
push rdi
push rsi
push rax ; save buffer
push rdx ; save count
; poll event
mov rdi, poll_fd ; pointer to struct
mov rsi, 1 ; only 1 fd - stdin
mov rdx, 0 ; timeout
SYS POLL
mov rsi, rax
pop rdx ; restore count
pop rax ; restore buffer
test rsi, rsi ; test if no event
jz .no_event
; read input
call read
jmp .exit
.no_event:
mov byte [rax], -1
.exit:
pop rsi
pop rdi
ret
global write
; rax: pointer to string
; rdx: string length
; rcx: fd
write:
push rdi
push rsi
mov rsi, rax ; string pointer
mov rdi, rcx ; fd
SYS WRITE
pop rsi
pop rdi
ret
global read
; rax: buffer
; rdx: count
read:
push rdi
push rsi
mov rsi, rax
mov rdi, STDIN
.loop:
SYS READ
; exit if EOF
test rax, rax
je .exit
; exit if read as many bytes as requested
cmp rax, rdx
je .exit
; read less then requested, repeat syscall
sub rdx, rax
jmp .loop
.exit:
pop rsi
pop rdi
ret
section .data
DEF_STR_DATA text_syscall_err, "System call failed!", 10
section .text
syscall_err:
mov rax, text_syscall_err
mov rdx, text_syscall_err_len
mov rcx, STDERR
call write
call exit
; vim:ft=nasm