https://github.com/akkartik/mu/blob/main/126write-int-decimal.subx
  1 
  2 
  3 == code
  4 
  5 
  6 
  7 
  8 write-int32-decimal:  
  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     55/push-ebp
 40     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 
 41     
 42     50/push-eax
 43     51/push-ecx
 44     52/push-edx
 45     53/push-ebx
 46     57/push-edi
 47     
 48     b9/copy-to-ecx  0xa/imm32
 49     
 50     68/push  0/imm32/sentinel
 51     
 52     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           0/r32/eax   0xc/disp8       .                 
 53     3d/compare-eax-with  0/imm32
 54     7d/jump-if->=  $write-int32-decimal:read-loop/disp8
 55 $write-int32-decimal:negative:
 56     f7          3/subop/negate      3/mod/direct    0/rm32/eax    .           .             .           .           .               .                 
 57 $write-int32-decimal:read-loop:
 58     
 59     99/sign-extend-eax-into-edx
 60     f7          7/subop/idiv        3/mod/direct    1/rm32/ecx    .           .             .           .           .               .                 
 61     
 62     81          0/subop/add         3/mod/direct    2/rm32/edx    .           .             .           .           .               0x30/imm32        
 63     
 64     52/push-edx
 65     
 66     3d/compare-eax-and  0/imm32
 67     7f/jump-if->  $write-int32-decimal:read-loop/disp8
 68 $write-int32-decimal:read-break:
 69     
 70     81          7/subop/compare     1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0xc/disp8       0/imm32           
 71     7d/jump-if->=  $write-int32-decimal:write/disp8
 72 $write-int32-decimal:push-negative:
 73     68/push  0x2d/imm32/-
 74 $write-int32-decimal:write:
 75     
 76     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           7/r32/edi   8/disp8         .                 
 77     
 78     8b/copy                         0/mod/indirect  7/rm32/edi    .           .             .           2/r32/edx   .               .                 
 79     
 80     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    7/base/edi  2/index/edx   .           1/r32/ecx   0xc/disp8       .                 
 81     
 82     8b/copy                         1/mod/*+disp8   7/rm32/edi    .           .             .           3/r32/ebx   8/disp8         .                 
 83     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    7/base/edi  3/index/ebx   .           3/r32/ebx   0xc/disp8       .                 
 84 $write-int32-decimal:write-loop:
 85     
 86     58/pop-to-eax
 87     
 88     3d/compare-eax-and  0/imm32/sentinel
 89     74/jump-if-=  $write-int32-decimal:write-break/disp8
 90     
 91     39/compare                      3/mod/direct    1/rm32/ecx    .           .             .           3/r32/ebx   .               .                 
 92     73/jump-if-addr>=  $write-int32-decimal:abort/disp8
 93 $write-int32-decimal:write-char:
 94     
 95     88/copy-byte                    0/mod/indirect  1/rm32/ecx    .           .             .           0/r32/AL    .               .                 
 96     
 97     41/increment-ecx
 98     
 99     42/increment-edx
100     eb/jump  $write-int32-decimal:write-loop/disp8
101 $write-int32-decimal:write-break:
102     
103     89/copy                         0/mod/indirect  7/rm32/edi    .           .             .           2/r32/edx   .               .                 
104 $write-int32-decimal:end:
105     
106     5f/pop-to-edi
107     5b/pop-to-ebx
108     5a/pop-to-edx
109     59/pop-to-ecx
110     58/pop-to-eax
111     
112     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 
113     5d/pop-to-ebp
114     c3/return
115 
116 $write-int32-decimal:abort:
117     (abort "write-int32-decimal: stream out of space")
118     
119 
120 test-write-int32-decimal:
121     
122     
123     
124     
125     68/push  _test-stream/imm32
126     
127     e8/call  clear-stream/disp32
128     
129     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           
130     
131     
132     68/push  9/imm32
133     68/push  _test-stream/imm32
134     
135     e8/call  write-int32-decimal/disp32
136     
137     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           
138     
139     
140     68/push  "F - test-write-int32-decimal"/imm32
141     68/push  "9"/imm32
142     68/push  _test-stream/imm32
143     
144     e8/call  check-stream-equal/disp32
145     
146     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         
147     
148     c3/return
149 
150 test-write-int32-decimal-zero:
151     
152     
153     
154     
155     68/push  _test-stream/imm32
156     
157     e8/call  clear-stream/disp32
158     
159     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           
160     
161     
162     68/push  0/imm32
163     68/push  _test-stream/imm32
164     
165     e8/call  write-int32-decimal/disp32
166     
167     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           
168     
169     
170     68/push  "F - test-write-int32-decimal-zero"/imm32
171     68/push  "0"/imm32
172     68/push  _test-stream/imm32
173     
174     e8/call  check-stream-equal/disp32
175     
176     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         
177     
178     c3/return
179 
180 test-write-int32-decimal-multiple-digits:
181     
182     
183     
184     
185     68/push  _test-stream/imm32
186     
187     e8/call  clear-stream/disp32
188     
189     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           
190     
191     
192     68/push  0xa/imm32
193     68/push  _test-stream/imm32
194     
195     e8/call  write-int32-decimal/disp32
196     
197     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           
198     
199     
200     68/push  "F - test-write-int32-decimal-multiple-digits"/imm32
201     68/push  "10"/imm32
202     68/push  _test-stream/imm32
203     
204     e8/call  check-stream-equal/disp32
205     
206     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         
207     
208     c3/return
209 
210 test-write-int32-decimal-negative:
211     
212     
213     
214     
215     68/push  _test-stream/imm32
216     
217     e8/call  clear-stream/disp32
218     
219     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           
220     
221     
222     68/push  -9/imm32
223     68/push  _test-stream/imm32
224     
225     e8/call  write-int32-decimal/disp32
226     
227     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           
228 +-- 26 lines: #?     # dump _test-stream ------------------------------------------------------------------------------------------------------------------------------------------------
254     
255     
256     68/push  "F - test-write-int32-decimal-negative"/imm32
257     68/push  "-9"/imm32
258     68/push  _test-stream/imm32
259     
260     e8/call  check-stream-equal/disp32
261     
262     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         
263     
264     c3/return
265 
266 
267 
268 test-write-int32-decimal-indefinite-integer:
269     
270     
271     
272     68/push  _test-stream/imm32
273     
274     e8/call  clear-stream/disp32
275     
276     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           
277     
278     
279     68/push  0x80000000/imm32
280     68/push  _test-stream/imm32
281     
282     e8/call  write-int32-decimal/disp32
283     
284     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           
285     
286     
287     68/push  "F - test-write-int32-decimal-indefinite-integer"/imm32
288     68/push  "-("/imm32
289     68/push  _test-stream/imm32
290     
291     e8/call  check-stream-equal/disp32
292     
293     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         
294     
295     c3/return
296 
297 test-write-int32-decimal-negative-multiple-digits:
298     
299     
300     
301     
302     68/push  _test-stream/imm32
303     
304     e8/call  clear-stream/disp32
305     
306     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           
307     
308     
309     68/push  -0xa/imm32
310     68/push  _test-stream/imm32
311     
312     e8/call  write-int32-decimal/disp32
313     
314     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           
315     
316     
317     68/push  "F - test-write-int32-decimal-negative-multiple-digits"/imm32
318     68/push  "-10"/imm32
319     68/push  _test-stream/imm32
320     
321     e8/call  check-stream-equal/disp32
322     
323     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         
324     
325     c3/return
326 
327 decimal-digit?:  
328     
329     55/push-ebp
330     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 
331     
332     51/push-ecx
333     
334     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           1/r32/ecx   8/disp8         .                 
335     
336     b8/copy-to-eax  0/imm32/false
337     
338     81          7/subop/compare     3/mod/direct    1/rm32/ecx    .           .             .           .           .               0x30/imm32        
339     7c/jump-if-<  $decimal-digit?:end/disp8
340     
341     81          7/subop/compare     3/mod/direct    1/rm32/ecx    .           .             .           .           .               0x39/imm32        
342     7f/jump-if->  $decimal-digit?:end/disp8
343 $decimal-digit?:true:
344     b8/copy-to-eax  1/imm32/true
345 $decimal-digit?:end:
346     
347     59/pop-to-ecx
348     
349     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 
350     5d/pop-to-ebp
351     c3/return
352 
353 test-decimal-digit-below-0:
354     
355     
356     68/push  0x2f/imm32
357     
358     e8/call  decimal-digit?/disp32
359     
360     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           
361     
362     
363     68/push  "F - test-decimal-digit-below-0"/imm32
364     68/push  0/imm32/false
365     50/push-eax
366     
367     e8/call  check-ints-equal/disp32
368     
369     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         
370     c3/return
371 
372 test-decimal-digit-0-to-9:
373     
374     
375     68/push  0x30/imm32
376     
377     e8/call  decimal-digit?/disp32
378     
379     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           
380     
381     
382     68/push  "F - test-decimal-digit-at-0"/imm32
383     68/push  1/imm32/true
384     50/push-eax
385     
386     e8/call  check-ints-equal/disp32
387     
388     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         
389     
390     
391     68/push  0x39/imm32
392     
393     e8/call  decimal-digit?/disp32
394     
395     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           
396     
397     
398     68/push  "F - test-decimal-digit-at-9"/imm32
399     68/push  1/imm32/true
400     50/push-eax
401     
402     e8/call  check-ints-equal/disp32
403     
404     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         
405     c3/return
406 
407 test-decimal-digit-above-9:
408     
409     
410     68/push  0x3a/imm32
411     
412     e8/call  decimal-digit?/disp32
413     
414     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           
415     
416     
417     68/push  "F - test-decimal-digit-above-9"/imm32
418     68/push  0/imm32/false
419     50/push-eax
420     
421     e8/call  check-ints-equal/disp32
422     
423     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         
424     c3/return
425 
426 to-decimal-digit:  
427     
428     55/push-ebp
429     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 
430     
431     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           0/r32/eax   8/disp8         .                 
432 $to-decimal-digit:check0:
433     
434     3d/compare-eax-with  0x30/imm32/0
435     7c/jump-if-<  $to-decimal-digit:abort/disp8
436 $to-decimal-digit:check1:
437     
438     3d/compare-eax-with  0x39/imm32/f
439     7f/jump-if->  $to-decimal-digit:abort/disp8
440 $to-decimal-digit:digit:
441     
442     2d/subtract-from-eax  0x30/imm32/0
443 $to-decimal-digit:end:
444     
445     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 
446     5d/pop-to-ebp
447     c3/return
448 
449 $to-decimal-digit:abort:
450     (abort "to-decimal-digit: not a digit character")
451     
452 
453