-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathlib.asm
More file actions
316 lines (255 loc) · 4.62 KB
/
lib.asm
File metadata and controls
316 lines (255 loc) · 4.62 KB
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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
section .data
newline_char: db 10
section .text
global string_length
global print_string
global print_error
global print_char
global print_newline
global print_uint
global print_int
global string_equals
global read_char
global read_word
global parse_uint
global parse_int
global string_copy
string_length:
xor rax, rax
.loop:
cmp byte [rdi+rax],0
je .end
inc rax
jmp .loop
.end:
ret
print_string:
call string_length ; rax contains string lenght
mov rdx, rax ; rdx -> how many bytes to write
mov rax, 1 ; 'write' syscall identifier
mov rsi, rdi ; where to take data from
mov rdi, 1 ; stdout file descriptor
syscall
ret
print_error:
call string_length ; rax contains string lenght
mov rdx, rax ; rdx -> how many bytes to write
mov rax, 1 ; 'write' syscall identifier
mov rsi, rdi ; where to take data from
mov rdi, 2 ; stderr file descriptor
syscall
ret
print_char:
mov rax, 1
push rdi
mov rsi, rsp
mov rdi, 1
mov rdx, 1
syscall
pop rdi
ret
print_newline:
mov rdi, newline_char
call print_char
ret
print_uint:
mov rax, rdi
mov rsi, rsp
mov rdi, 10
cmp rdi, 0 ; reset zero flag
.loop:
jz .print
xor rdx, rdx
div rdi
push rdx
test rax, rax
jnz .loop
.print:
cmp rsi, rsp
je .end
pop rdi
add rdi, '0'
push rsi
call print_char
pop rsi
jmp .print
.end:
ret
print_int:
cmp rdi, 0
jge .print_uint
push rdi
mov rdi, '-'
call print_char
pop rdi
neg rdi
.print_uint:
call print_uint
ret
string_equals:
call string_length
mov rdx, rax
push rdi
mov rdi, rsi
call string_length
pop rdi
cmp rdx, rax
jne .return_zero
xor rdx, rdx
.compare_char:
cmp rdx, rax
je .return_one
mov r8b, [rdi + rdx]
cmp r8b, [rsi + rdx]
jne .return_zero
inc rdx
jmp .compare_char
.return_one:
mov rax, 1
jmp .end
.return_zero:
mov rax, 0
.end:
ret
read_char:
push 0
mov rsi, rsp ; where to write data to
mov rdx, 1 ; rdx -> how many bytes to write
xor rax, rax ; 'read' syscall identifier
xor rdi, rdi ; stdin file descriptor
syscall
pop rax
ret
read_word:
push rbx
xor rbx, rbx
.loopA:
push rdi
push rsi
call read_char
pop rsi
pop rdi
cmp al, 0x20
je .loopA
cmp al, 0x9
je .loopA
cmp al, 0xa
je .loopA
cmp rbx, rsi
jae .error
cmp al, 0
je .end
mov byte [rdi + rbx], al
inc rbx
.loopB:
push rdi
push rsi
call read_char
pop rsi
pop rdi
cmp rbx, rsi
jae .error
cmp al, 0x20
je .end
cmp al, 0x9
je .end
cmp al, 0xa
je .end
cmp al, 0
je .end
mov byte [rdi + rbx], al
inc rbx
jmp .loopB
.error:
mov rax, 0
pop rbx
ret
.end:
mov byte [rdi + rbx], 0
mov rax, rdi
pop rbx
ret
; rdi points to a string
; returns rax: number, rdx : length
parse_uint:
push rbx
call string_length
mov rdx, rax
xor rsi, rsi ; final value
mov r11, 2 ; value for division
mov r10, 10 ; value for multiplication
mov r8, 0 ; char position
.next_char:
xor rcx, rcx ; bit position
xor rbx, rbx ; number
mov r9b, [rdi + r8]
sub r9b, '0'
cmp r9b, 10
ja .end
mov rax, rsi
push rdx
mul r10 ; multiply final value with 10
pop rdx
mov rsi, rax
xor rax, rax
mov al, r9b
.char_division:
div r11b
sal ah, cl
or bl, ah
cmp cl, 3
je .add_value
inc cl
xor ah, ah
jmp .char_division
.add_value:
add rsi, rbx
inc r8
cmp r8, rdx
je .end
jmp .next_char
.end:
mov rax, rsi
mov rdx, r8
pop rbx
ret
; rdi points to a string
; returns rax: number, rdx : length
parse_int:
cmp byte [rdi], '-'
je .parse_neg
call parse_uint
jmp .end
.parse_neg:
inc rdi
call parse_uint
neg rax
inc rdx
.end:
ret
string_copy:
push rdi
push rsi
push rdx
call string_length
pop rdx
pop rsi
pop rdi
cmp rax, rdx
jae .return_zero
mov rdx, 0
.loop:
cmp rdx, rax
je .null_terminate
mov cl, [rdi + rdx]
mov [rsi + rdx], cl
inc rdx
jmp .loop
.null_terminate:
mov byte [rsi + rdx], 0
mov rax, rsi
jmp .end
.return_zero:
mov rax, 0
.end:
ret