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