https://github.com/akkartik/mu/blob/main/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       25/and-eax-with 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       (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
428 
429 _parse-array-of-decimal-ints:  
430     
431     
432     
433     
434     
435     
436     
437     
438     
439     
440     
441     
442     
443     
444     
445     
446     
447     
448     
449     
450     
451     
452     
453     
454     55/push-ebp
455     89/<- %ebp 4/r32/esp
456     
457     50/push-eax
458     51/push-ecx
459     52/push-edx
460     53/push-ebx
461     56/push-esi
462     57/push-edi
463     
464     8b/-> *(ebp+0xc) 6/r32/esi
465     
466     8d/copy-address *(esi+4) 1/r32/ecx
467     
468     
469     8b/-> *esi 2/r32/edx
470     
471     01/add-to %edx 1/r32/ecx
472     
473     31/xor-with %ebx 3/r32/ebx
474 $_parse-array-of-decimal-ints:loop1:
475     
476     39/compare %ecx 2/r32/edx
477     73/jump-if-addr>= $_parse-array-of-decimal-ints:break1/disp8
478     
479     (skip-chars-matching-in-slice %ecx %edx 0x20)  
480     89/<- %ecx 0/r32/eax
481     
482     39/compare %ecx 2/r32/edx
483     73/jump-if-addr>= $_parse-array-of-decimal-ints:break1/disp8
484     
485     (skip-chars-not-matching-in-slice %ecx %edx 0x20)  
486     89/<- %ecx 0/r32/eax
487     
488     81 0/subop/add %ebx 4/imm32
489     eb/jump $_parse-array-of-decimal-ints:loop1/disp8
490 $_parse-array-of-decimal-ints:break1:
491     (allocate-array *(ebp+8) %ebx *(ebp+0x10))
492 $_parse-array-of-decimal-ints:pass2:
493     
494     68/push 0/imm32/end
495     8d/copy-address *(esi+4) 7/r32/edi
496     57/push-edi
497     89/<- %edi 4/r32/esp
498     
499     8b/-> *(ebp+0x10) 0/r32/eax
500     (lookup *eax *(eax+4))  
501     8d/copy-address *(eax+4) 1/r32/ecx
502 $_parse-array-of-decimal-ints:loop2:
503     
504     39/compare *edi 2/r32/edx
505     73/jump-if-addr>= $_parse-array-of-decimal-ints:end/disp8
506     
507     (skip-chars-matching-in-slice *edi %edx 0x20)  
508     89/<- *edi 0/r32/eax
509     
510     39/compare *edi 2/r32/edx
511     73/jump-if-addr>= $_parse-array-of-decimal-ints:end/disp8
512     
513     (skip-chars-not-matching-in-slice *edi %edx 0x20)  
514     89/<- *(edi+4) 0/r32/eax
515     
516     (parse-decimal-int-from-slice %edi)
517     89/<- *ecx 0/r32/eax
518     
519     81 0/subop/add %ecx 4/imm32
520     
521     8b/-> *(edi+4) 0/r32/eax
522     89/<- *edi 0/r32/eax
523     eb/jump $_parse-array-of-decimal-ints:loop2/disp8
524 $_parse-array-of-decimal-ints:end:
525     
526     81 0/subop/add %esp 8/imm32
527     
528     5f/pop-to-edi
529     5e/pop-to-esi
530     5b/pop-to-ebx
531     5a/pop-to-edx
532     59/pop-to-ecx
533     58/pop-to-eax
534     
535     89/<- %esp 5/r32/ebp
536     5d/pop-to-ebp
537     c3/return
538 
539 test-parse-array-of-decimal-ints:
540     
541     55/push-ebp
542     89/<- %ebp 4/r32/esp
543     
544     68/push 0/imm32
545     68/push 0/imm32
546     89/<- %esi 4/r32/esp
547     
548     68/push 3/imm32
549     68/push 2/imm32
550     68/push 1/imm32
551     68/push 0xc/imm32/size
552     89/<- %ecx 4/r32/esp
553     
554     (_parse-array-of-decimal-ints Heap "1 2 3" %esi)
555     (lookup *esi *(esi+4))  
556     (array-equal? %ecx %eax)  
557     (check-ints-equal %eax 1 "F - test-parse-array-of-decimal-ints")
558     
559     89/<- %esp 5/r32/ebp
560     5d/pop-to-ebp
561     c3/return
562 
563 test-parse-array-of-decimal-ints-empty:
564     
565     
566     55/push-ebp
567     89/<- %ebp 4/r32/esp
568     
569     68/push 0/imm32
570     68/push 0/imm32
571     89/<- %esi 4/r32/esp
572     
573     (_parse-array-of-decimal-ints Heap "" %esi)
574     (lookup *esi *(esi+4))  
575     (check-ints-equal *eax 0 "F - test-parse-array-of-decimal-ints-empty")
576     
577     89/<- %esp 5/r32/ebp
578     5d/pop-to-ebp
579     c3/return
580 
581 test-parse-array-of-decimal-ints-just-whitespace:
582     
583     
584     55/push-ebp
585     89/<- %ebp 4/r32/esp
586     
587     68/push 0/imm32
588     68/push 0/imm32
589     89/<- %esi 4/r32/esp
590     
591     (_parse-array-of-decimal-ints Heap Space %esi)
592     (lookup *esi *(esi+4))  
593     (check-ints-equal *eax 0 "F - test-parse-array-of-decimal-ints-just-whitespace")
594     
595     89/<- %esp 5/r32/ebp
596     5d/pop-to-ebp
597     c3/return
598 
599 test-parse-array-of-decimal-ints-extra-whitespace:
600     
601     55/push-ebp
602     89/<- %ebp 4/r32/esp
603     
604     68/push 0/imm32
605     68/push 0/imm32
606     89/<- %esi 4/r32/esp
607     
608     68/push 3/imm32
609     68/push 2/imm32
610     68/push 1/imm32
611     68/push 0xc/imm32/size
612     89/<- %ecx 4/r32/esp
613     
614     (_parse-array-of-decimal-ints Heap " 1 2  3  " %esi)
615     (lookup *esi *(esi+4))  
616     (array-equal? %ecx %eax)  
617     (check-ints-equal %eax 1 "F - test-parse-array-of-decimal-ints-extra-whitespace")
618     
619     89/<- %esp 5/r32/ebp
620     5d/pop-to-ebp
621     c3/return
622 
623 parse-array-of-decimal-ints:  
624     
625     55/push-ebp
626     89/<- %ebp 4/r32/esp
627     
628     (_parse-array-of-decimal-ints Heap *(ebp+8) *(ebp+0xc))
629 $parse-array-of-decimal-ints:end:
630     
631     89/<- %esp 5/r32/ebp
632     5d/pop-to-ebp
633     c3/return