https://github.com/akkartik/mu/blob/main/baremetal/311decimal-int.subx
1
2
3
4 parse-decimal-int-from-slice:
5
6 55/push-ebp
7 89/<- %ebp 4/r32/esp
8
9 51/push-ecx
10
11 8b/-> *(ebp+8) 1/r32/ecx
12
13 (parse-decimal-int-helper *ecx *(ecx+4))
14 $parse-decimal-int-from-slice:end:
15
16 59/pop-to-ecx
17
18 89/<- %esp 5/r32/ebp
19 5d/pop-to-ebp
20 c3/return
21
22
23 parse-decimal-int:
24
25 55/push-ebp
26 89/<- %ebp 4/r32/esp
27
28 51/push-ecx
29 52/push-edx
30
31 8b/-> *(ebp+8) 0/r32/eax
32
33 8d/copy-address *(eax+4) 1/r32/ecx
34
35 8b/-> *eax 2/r32/edx
36 8d/copy-address *(eax+edx+4) 2/r32/edx
37
38 (parse-decimal-int-helper %ecx %edx)
39 $parse-decimal-int:end:
40
41 5a/pop-to-edx
42 59/pop-to-ecx
43
44 89/<- %esp 5/r32/ebp
45 5d/pop-to-ebp
46 c3/return
47
48 parse-decimal-int-from-stream:
49
50 55/push-ebp
51 89/<- %ebp 4/r32/esp
52
53 51/push-ecx
54 52/push-edx
55
56 8b/-> *(ebp+8) 0/r32/eax
57
58 8b/-> *(eax+4) 1/r32/ecx
59 8d/copy-address *(eax+ecx+0xc) 1/r32/ecx
60
61 8b/-> *eax 2/r32/edx
62 8d/copy-address *(eax+edx+0xc) 2/r32/edx
63
64 {
65
66 4a/decrement-edx
67
68 8a/byte-> *edx 0/r32/eax
69 81 4/subop/and %eax 0xff/imm32
70 3d/compare-eax-and 0xa/imm32/newline
71 74/jump-if-= break/disp8
72
73 42/increment-edx
74 }
75
76 (parse-decimal-int-helper %ecx %edx)
77 $parse-decimal-int-from-stream:end:
78
79 5a/pop-to-edx
80 59/pop-to-ecx
81
82 89/<- %esp 5/r32/ebp
83 5d/pop-to-ebp
84 c3/return
85
86 parse-decimal-int-helper:
87
88 55/push-ebp
89 89/<- %ebp 4/r32/esp
90
91 51/push-ecx
92 52/push-edx
93 53/push-ebx
94 56/push-esi
95 57/push-edi
96
97 8b/-> *(ebp+8) 6/r32/esi
98
99 8b/-> *(ebp+0xc) 7/r32/edi
100
101 ba/copy-to-edx 0/imm32/false
102
103 {
104 $parse-decimal-int-helper:negative:
105 b8/copy-to-eax 0/imm32
106 8a/copy-byte *esi 0/r32/AL
107 3d/compare-eax-and 0x2d/imm32/-
108 75/jump-if-!= break/disp8
109
110 46/increment-esi
111
112 ba/copy-to-edx 1/imm32/true
113 }
114
115 52/push-edx
116
117 b8/copy-to-eax 0/imm32
118
119 b9/copy-to-ecx 0/imm32
120
121 bb/copy-to-ebx 0xa/imm32
122 {
123 $parse-decimal-int-helper:loop:
124
125 39/compare %esi 7/r32/edi
126 73/jump-if-addr>= break/disp8
127
128 8a/copy-byte *esi 1/r32/CL
129 50/push-eax
130 (is-decimal-digit? %ecx)
131 {
132 3d/compare-eax-and 0/imm32/false
133 75/jump-if-!= break/disp8
134 58/pop-to-eax
135 b8/copy-to-eax 0/imm32
136 eb/jump $parse-decimal-int-helper:negate/disp8
137 }
138 58/pop-to-eax
139
140 81 5/subop/subtract %ecx 0x30/imm32/zero
141
142
143 ba/copy-to-edx 0/imm32
144 f7 4/subop/multiply-into-edx-eax %ebx
145
146 01/add %eax 1/r32/ecx
147
148 46/increment-esi
149
150 eb/jump loop/disp8
151 }
152 $parse-decimal-int-helper:negate:
153
154 5a/pop-to-edx
155 {
156 81 7/subop/compare %edx 0/imm32/false
157 74/jump-if-= break/disp8
158 f7 3/subop/negate %eax
159 }
160 $parse-decimal-int-helper:end:
161
162 5f/pop-to-edi
163 5e/pop-to-esi
164 5b/pop-to-ebx
165 5a/pop-to-edx
166 59/pop-to-ecx
167
168 89/<- %esp 5/r32/ebp
169 5d/pop-to-ebp
170 c3/return
171
172 test-parse-decimal-int-from-slice-single-digit:
173
174 55/push-ebp
175 89/<- %ebp 4/r32/esp
176
177 50/push-eax
178 51/push-ecx
179
180 b8/copy-to-eax "3"/imm32
181 8b/-> *eax 1/r32/ecx
182 8d/copy-address *(eax+ecx+4) 1/r32/ecx
183 05/add-to-eax 4/imm32
184
185 51/push-ecx
186 50/push-eax
187 89/<- %ecx 4/r32/esp
188
189 (parse-decimal-int-from-slice %ecx)
190 (check-ints-equal %eax 3 "F - test-parse-decimal-int-from-slice-single-digit")
191 $test-parse-decimal-int-helper-single-digit:end:
192
193 59/pop-to-ecx
194 58/pop-to-eax
195
196 89/<- %esp 5/r32/ebp
197 5d/pop-to-ebp
198 c3/return
199
200 test-parse-decimal-int-from-slice-multi-digit:
201
202 55/push-ebp
203 89/<- %ebp 4/r32/esp
204
205 50/push-eax
206 51/push-ecx
207
208 b8/copy-to-eax "34"/imm32
209 8b/-> *eax 1/r32/ecx
210 8d/copy-address *(eax+ecx+4) 1/r32/ecx
211 05/add-to-eax 4/imm32
212
213 51/push-ecx
214 50/push-eax
215 89/<- %ecx 4/r32/esp
216
217 (parse-decimal-int-from-slice %ecx)
218 (check-ints-equal %eax 0x22 "F - test-parse-decimal-int-from-slice-multi-digit")
219 $test-parse-decimal-int-helper-multi-digit:end:
220
221 59/pop-to-ecx
222 58/pop-to-eax
223
224 89/<- %esp 5/r32/ebp
225 5d/pop-to-ebp
226 c3/return
227
228 test-parse-decimal-int-from-slice-zero:
229
230 55/push-ebp
231 89/<- %ebp 4/r32/esp
232
233 50/push-eax
234 51/push-ecx
235
236 b8/copy-to-eax "00"/imm32
237 8b/-> *eax 1/r32/ecx
238 8d/copy-address *(eax+ecx+4) 1/r32/ecx
239 05/add-to-eax 4/imm32
240
241 51/push-ecx
242 50/push-eax
243 89/<- %ecx 4/r32/esp
244
245 (parse-decimal-int-from-slice %ecx)
246 (check-ints-equal %eax 0 "F - test-parse-decimal-int-from-slice-zero")
247 $test-parse-decimal-int-helper-zero:end:
248
249 59/pop-to-ecx
250 58/pop-to-eax
251
252 89/<- %esp 5/r32/ebp
253 5d/pop-to-ebp
254 c3/return
255
256 test-parse-decimal-int-from-slice-negative:
257
258 55/push-ebp
259 89/<- %ebp 4/r32/esp
260
261 50/push-eax
262 51/push-ecx
263
264 b8/copy-to-eax "-3"/imm32
265 8b/-> *eax 1/r32/ecx
266 8d/copy-address *(eax+ecx+4) 1/r32/ecx
267 05/add-to-eax 4/imm32
268
269 51/push-ecx
270 50/push-eax
271 89/<- %ecx 4/r32/esp
272
273 (parse-decimal-int-from-slice %ecx)
274 (check-ints-equal %eax -3 "F - test-parse-decimal-int-from-slice-negative")
275 $test-parse-decimal-int-helper-negative:end:
276
277 59/pop-to-ecx
278 58/pop-to-eax
279
280 89/<- %esp 5/r32/ebp
281 5d/pop-to-ebp
282 c3/return
283
284 test-parse-decimal-int-from-slice-multi-digit-negative:
285
286 55/push-ebp
287 89/<- %ebp 4/r32/esp
288
289 50/push-eax
290 51/push-ecx
291
292 b8/copy-to-eax "-32"/imm32
293 8b/-> *eax 1/r32/ecx
294 8d/copy-address *(eax+ecx+4) 1/r32/ecx
295 05/add-to-eax 4/imm32
296
297 51/push-ecx
298 50/push-eax
299 89/<- %ecx 4/r32/esp
300
301 (parse-decimal-int-from-slice %ecx)
302 (check-ints-equal %eax -0x20 "F - test-parse-decimal-int-from-slice-multi-digit-negative")
303 $test-parse-decimal-int-helper-multi-digit-negative:end:
304
305 59/pop-to-ecx
306 58/pop-to-eax
307
308 89/<- %esp 5/r32/ebp
309 5d/pop-to-ebp
310 c3/return
311
312 decimal-size:
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327 55/push-ebp
328 89/<- %ebp 4/r32/esp
329
330 51/push-ecx
331 52/push-edx
332 57/push-edi
333
334 bf/copy-to-edi 0/imm32
335
336 8b/-> *(ebp+8) 0/r32/eax
337
338 {
339 3d/compare-eax-with 0/imm32
340 7d/jump-if->= break/disp8
341 f7 3/subop/negate %eax
342 47/increment-edi
343 }
344
345 b9/copy-to-ecx 0xa/imm32
346 {
347 ba/copy-to-edx 0/imm32
348 f7 7/subop/idiv-edx-eax-by %ecx
349 47/increment-edi
350 3d/compare-eax-and 0/imm32
351 75/jump-if-!= loop/disp8
352 }
353 $decimal-size:end:
354 89/<- %eax 7/r32/edi
355
356 5f/pop-to-edi
357 5a/pop-to-edx
358 59/pop-to-ecx
359
360 89/<- %esp 5/r32/ebp
361 5d/pop-to-ebp
362 c3/return
363
364 test-decimal-size-of-zero:
365
366 55/push-ebp
367 89/<- %ebp 4/r32/esp
368
369 (decimal-size 0)
370 (check-ints-equal %eax 1 "F - test-decimal-size-of-zero")
371 $test-decimal-size-of-zero:end:
372
373 89/<- %esp 5/r32/ebp
374 5d/pop-to-ebp
375 c3/return
376
377 test-decimal-size-single-digit:
378
379 55/push-ebp
380 89/<- %ebp 4/r32/esp
381
382 (decimal-size 4)
383 (check-ints-equal %eax 1 "F - test-decimal-size-single-digit")
384 $test-decimal-size-single-digit:end:
385
386 89/<- %esp 5/r32/ebp
387 5d/pop-to-ebp
388 c3/return
389
390 test-decimal-size-multi-digit:
391
392 55/push-ebp
393 89/<- %ebp 4/r32/esp
394
395 (decimal-size 0xa)
396 (check-ints-equal %eax 2 "F - test-decimal-size-multi-digit")
397 $test-decimal-size-multi-digit:end:
398
399 89/<- %esp 5/r32/ebp
400 5d/pop-to-ebp
401 c3/return
402
403 test-decimal-size-single-digit-negative:
404
405 55/push-ebp
406 89/<- %ebp 4/r32/esp
407
408 (decimal-size -4)
409 (check-ints-equal %eax 2 "F - test-decimal-size-single-digit-negative")
410 $test-decimal-size-single-digit-negative:end:
411
412 89/<- %esp 5/r32/ebp
413 5d/pop-to-ebp
414 c3/return
415
416 test-decimal-size-multi-digit-negative:
417
418 55/push-ebp
419 89/<- %ebp 4/r32/esp
420
421 (decimal-size -0xa)
422 (check-ints-equal %eax 3 "F - test-decimal-size-multi-digit-negative")
423 $test-decimal-size-multi-digit-negative:end:
424
425 89/<- %esp 5/r32/ebp
426 5d/pop-to-ebp
427 c3/return