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 test-write-int32-decimal-negative-multiple-digits:
267
268
269
270
271 68/push _test-stream/imm32
272
273 e8/call clear-stream/disp32
274
275 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
276
277
278 68/push -0xa/imm32
279 68/push _test-stream/imm32
280
281 e8/call write-int32-decimal/disp32
282
283 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
284
285
286 68/push "F - test-write-int32-decimal-negative-multiple-digits"/imm32
287 68/push "-10"/imm32
288 68/push _test-stream/imm32
289
290 e8/call check-stream-equal/disp32
291
292 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32
293
294 c3/return
295
296 decimal-digit?:
297
298 55/push-ebp
299 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . .
300
301 51/push-ecx
302
303 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 8/disp8 .
304
305 b8/copy-to-eax 0/imm32/false
306
307 81 7/subop/compare 3/mod/direct 1/rm32/ecx . . . . . 0x30/imm32
308 7c/jump-if-< $decimal-digit?:end/disp8
309
310 81 7/subop/compare 3/mod/direct 1/rm32/ecx . . . . . 0x39/imm32
311 7f/jump-if-> $decimal-digit?:end/disp8
312 $decimal-digit?:true:
313 b8/copy-to-eax 1/imm32/true
314 $decimal-digit?:end:
315
316 59/pop-to-ecx
317
318 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . .
319 5d/pop-to-ebp
320 c3/return
321
322 test-decimal-digit-below-0:
323
324
325 68/push 0x2f/imm32
326
327 e8/call decimal-digit?/disp32
328
329 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
330
331
332 68/push "F - test-decimal-digit-below-0"/imm32
333 68/push 0/imm32/false
334 50/push-eax
335
336 e8/call check-ints-equal/disp32
337
338 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32
339 c3/return
340
341 test-decimal-digit-0-to-9:
342
343
344 68/push 0x30/imm32
345
346 e8/call decimal-digit?/disp32
347
348 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
349
350
351 68/push "F - test-decimal-digit-at-0"/imm32
352 68/push 1/imm32/true
353 50/push-eax
354
355 e8/call check-ints-equal/disp32
356
357 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32
358
359
360 68/push 0x39/imm32
361
362 e8/call decimal-digit?/disp32
363
364 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
365
366
367 68/push "F - test-decimal-digit-at-9"/imm32
368 68/push 1/imm32/true
369 50/push-eax
370
371 e8/call check-ints-equal/disp32
372
373 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32
374 c3/return
375
376 test-decimal-digit-above-9:
377
378
379 68/push 0x3a/imm32
380
381 e8/call decimal-digit?/disp32
382
383 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
384
385
386 68/push "F - test-decimal-digit-above-9"/imm32
387 68/push 0/imm32/false
388 50/push-eax
389
390 e8/call check-ints-equal/disp32
391
392 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32
393 c3/return
394
395 to-decimal-digit:
396
397 55/push-ebp
398 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . .
399
400 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 .
401 $to-decimal-digit:check0:
402
403 3d/compare-eax-with 0x30/imm32/0
404 7c/jump-if-< $to-decimal-digit:abort/disp8
405 $to-decimal-digit:check1:
406
407 3d/compare-eax-with 0x39/imm32/f
408 7f/jump-if-> $to-decimal-digit:abort/disp8
409 $to-decimal-digit:digit:
410
411 2d/subtract-from-eax 0x30/imm32/0
412 $to-decimal-digit:end:
413
414 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . .
415 5d/pop-to-ebp
416 c3/return
417
418 $to-decimal-digit:abort:
419 (abort "to-decimal-digit: not a digit character")
420
421
422