This repository was archived by the owner on Mar 24, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstdlib.s
More file actions
235 lines (187 loc) · 3.74 KB
/
stdlib.s
File metadata and controls
235 lines (187 loc) · 3.74 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
.globl _start
.globl print_bool
.globl print_int
.globl read_int
_start:
andq $~15, %rsp
call main
# exit(0)
movl $0x3c, %eax
xorl %edi, %edi
syscall
ud2
error:
movzxb (%rdi), %rdx
incq %rdi
movq %rdi, %rsi
movl $1, %eax
movl $2, %edi
syscall
movl $0x3c, %eax
movl $1, %edi
syscall
ud2
read_int:
leaq line_buffer(%rip), %rdi
movzxb buffer_len(%rip), %rdx
xorl %ecx, %ecx
.Lread_loop:
cmpb %dl, %cl
jb .Lcheck_char
leaq fail_to_read(%rip), %rdx
movzxb had_eof(%rip), %rax
testq %rax, %rax
cmovnzq %rdx, %rdi
jnz error
# need to read more into the buffer
pushq %rdi
pushq %rcx
xorl %eax, %eax
movq %rdi, %rsi
addq %rcx, %rsi
xorl %edi, %edi
movl $24, %edx
subq %rcx, %rdx
syscall
testq %rax, %rax
jnz .Lno_eof
movb $1, had_eof(%rip)
movb $'\n', (%rsi)
incq %rax
jmp .Lno_error
.Lno_eof:
leaq fail_to_read(%rip), %rdi
js error
.Lno_error:
popq %rcx
popq %rdi
addq %rcx, %rax
movq %rax, %rdx
.Lcheck_char:
movzxb (%rdi,%rcx), %rax
cmp $'\n', %al
je .Lfound_newline
incb %cl
cmpb $24, %cl
jne .Lread_loop
leaq line_too_long(%rip), %rdi
jmp error
.Lfound_newline:
xorl %r10d, %r10d
mov %dl, buffer_len(%rip)
movq %rcx, %r9
xorl %eax, %eax
leaq (%rdi,%rcx), %rsi
negq %rcx
.Lparse_loop:
movzxb (%rsi,%rcx), %rdx
cmpb $'-', %dl
je .Lminus
subb $'0', %dl
cmpb $9, %dl
leaq not_an_integer(%rip), %r8
cmovaq %r8, %rdi
ja error
shlq $1, %rax
leaq (%rax,%rax,4), %rax
addq %rdx, %rax
incb %cl
jnz .Lparse_loop
movq %rax, %rsi
negq %rsi
testq %r10, %r10
cmovnzq %rsi, %rax
movzxb buffer_len(%rip), %rdx
subq %r9, %rdx
decq %rdx
leaq 1(%rdi,%r9), %rsi
xorl %ecx, %ecx
movb %dl, buffer_len(%rip)
.Lcopy_loop:
movzxb (%rsi,%rcx), %r8
movb %r8b, (%rdi,%rcx)
incb %cl
cmpb %cl, %dl
jne .Lcopy_loop
ret
.Lminus:
addq %rcx, %rsi
cmpq %rsi, %rdi
leaq not_an_integer(%rip), %r8
cmovneq %r8, %rdi
jne error
subq %rcx, %rsi
cmpq $2, %r9
cmovbq %r8, %rdi
jb error
incb %r10b
incb %cl
jmp .Lparse_loop
print_int:
subq $8, %rsp
movq %rsp, %rsi
decq %rsi
movb $'\n', %dl
movb %dl, (%rsi)
testq %rdi, %rdi
jnz .Lnot_zero
decq %rsi
movb $'0', %dl
movb %dl, (%rsi)
jmp .Lprint_int_end
.Lnot_zero:
movq %rdi, %rax
negq %rax
cmovsq %rdi, %rax
movl $10, %ecx
.Lloop:
xorl %edx, %edx
decq %rsi
divq %rcx
addb $'0', %dl
movb %dl, (%rsi)
testq %rax, %rax
jnz .Lloop
.Lprint_int_end:
testq %rdi, %rdi
jns .Lprint
decq %rsi
movb $'-', (%rsi)
.Lprint:
movl $1, %eax
movl %eax, %edi
movq %rsp, %rdx
subq %rsi, %rdx
syscall
addq $8, %rsp
ret
print_bool:
leaq falsetrue(%rip), %rsi
movl $6, %edx
subl %edi, %edx
leaq (%rsi,%rdi,8), %rsi
movl $1, %eax
movl $1, %edi
syscall
ret
.section .rodata
falsetrue: .ascii "false\n\x00\x00true\n"
eof_on_read:
.byte eof_on_read_end - eof_on_read - 1
.ascii "got eof when reading int\n"
eof_on_read_end:
fail_to_read:
.byte fail_to_read_end - fail_to_read - 1
.ascii "failed to read from stdin\n"
fail_to_read_end:
line_too_long:
.byte line_too_long_end - line_too_long - 1
.ascii "tried to read 64-bit integer but line was too long\n"
line_too_long_end:
not_an_integer:
.byte not_an_integer_end - not_an_integer - 1
.ascii "tried to read an integer. did not get an integer\n"
not_an_integer_end:
.lcomm line_buffer, 24
.lcomm buffer_len, 1
.lcomm had_eof, 1