https://github.com/akkartik/mu/blob/main/linux/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
118
119 68/push "write-int32-decimal: out of space\n"/imm32
120 68/push 2/imm32/stderr
121
122 e8/call _write/disp32
123
124 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
125
126 bb/copy-to-ebx 1/imm32
127 e8/call syscall_exit/disp32
128
129
130 test-write-int32-decimal:
131
132
133
134
135 68/push _test-stream/imm32
136
137 e8/call clear-stream/disp32
138
139 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
140
141
142 68/push 9/imm32
143 68/push _test-stream/imm32
144
145 e8/call write-int32-decimal/disp32
146
147 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
148
149
150 68/push "F - test-write-int32-decimal"/imm32
151 68/push "9"/imm32
152 68/push _test-stream/imm32
153
154 e8/call check-stream-equal/disp32
155
156 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32
157
158 c3/return
159
160 test-write-int32-decimal-zero:
161
162
163
164
165 68/push _test-stream/imm32
166
167 e8/call clear-stream/disp32
168
169 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
170
171
172 68/push 0/imm32
173 68/push _test-stream/imm32
174
175 e8/call write-int32-decimal/disp32
176
177 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
178
179
180 68/push "F - test-write-int32-decimal-zero"/imm32
181 68/push "0"/imm32
182 68/push _test-stream/imm32
183
184 e8/call check-stream-equal/disp32
185
186 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32
187
188 c3/return
189
190 test-write-int32-decimal-multiple-digits:
191
192
193
194
195 68/push _test-stream/imm32
196
197 e8/call clear-stream/disp32
198
199 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
200
201
202 68/push 0xa/imm32
203 68/push _test-stream/imm32
204
205 e8/call write-int32-decimal/disp32
206
207 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
208
209
210 68/push "F - test-write-int32-decimal-multiple-digits"/imm32
211 68/push "10"/imm32
212 68/push _test-stream/imm32
213
214 e8/call check-stream-equal/disp32
215
216 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32
217
218 c3/return
219
220 test-write-int32-decimal-negative:
221
222
223
224
225 68/push _test-stream/imm32
226
227 e8/call clear-stream/disp32
228
229 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
230
231
232 68/push -9/imm32
233 68/push _test-stream/imm32
234
235 e8/call write-int32-decimal/disp32
236
237 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
238 +-- 26 lines: #? # dump _test-stream ------------------------------------------------------------------------------------------------------------------------------------------------
264
265
266 68/push "F - test-write-int32-decimal-negative"/imm32
267 68/push "-9"/imm32
268 68/push _test-stream/imm32
269
270 e8/call check-stream-equal/disp32
271
272 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32
273
274 c3/return
275
276 test-write-int32-decimal-negative-multiple-digits:
277
278
279
280
281 68/push _test-stream/imm32
282
283 e8/call clear-stream/disp32
284
285 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
286
287
288 68/push -0xa/imm32
289 68/push _test-stream/imm32
290
291 e8/call write-int32-decimal/disp32
292
293 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
294
295
296 68/push "F - test-write-int32-decimal-negative-multiple-digits"/imm32
297 68/push "-10"/imm32
298 68/push _test-stream/imm32
299
300 e8/call check-stream-equal/disp32
301
302 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32
303
304 c3/return
305
306 decimal-digit?:
307
308 55/push-ebp
309 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . .
310
311 51/push-ecx
312
313 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 8/disp8 .
314
315 b8/copy-to-eax 0/imm32/false
316
317 81 7/subop/compare 3/mod/direct 1/rm32/ecx . . . . . 0x30/imm32
318 7c/jump-if-< $decimal-digit?:end/disp8
319
320 81 7/subop/compare 3/mod/direct 1/rm32/ecx . . . . . 0x39/imm32
321 7f/jump-if-> $decimal-digit?:end/disp8
322 $decimal-digit?:true:
323 b8/copy-to-eax 1/imm32/true
324 $decimal-digit?:end:
325
326 59/pop-to-ecx
327
328 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . .
329 5d/pop-to-ebp
330 c3/return
331
332 test-decimal-digit-below-0:
333
334
335 68/push 0x2f/imm32
336
337 e8/call decimal-digit?/disp32
338
339 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
340
341
342 68/push "F - test-decimal-digit-below-0"/imm32
343 68/push 0/imm32/false
344 50/push-eax
345
346 e8/call check-ints-equal/disp32
347
348 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32
349 c3/return
350
351 test-decimal-digit-0-to-9:
352
353
354 68/push 0x30/imm32
355
356 e8/call decimal-digit?/disp32
357
358 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
359
360
361 68/push "F - test-decimal-digit-at-0"/imm32
362 68/push 1/imm32/true
363 50/push-eax
364
365 e8/call check-ints-equal/disp32
366
367 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32
368
369
370 68/push 0x39/imm32
371
372 e8/call decimal-digit?/disp32
373
374 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
375
376
377 68/push "F - test-decimal-digit-at-9"/imm32
378 68/push 1/imm32/true
379 50/push-eax
380
381 e8/call check-ints-equal/disp32
382
383 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32
384 c3/return
385
386 test-decimal-digit-above-9:
387
388
389 68/push 0x3a/imm32
390
391 e8/call decimal-digit?/disp32
392
393 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
394
395
396 68/push "F - test-decimal-digit-above-9"/imm32
397 68/push 0/imm32/false
398 50/push-eax
399
400 e8/call check-ints-equal/disp32
401
402 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32
403 c3/return
404
405 to-decimal-digit:
406
407 55/push-ebp
408 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . .
409
410 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 .
411 $to-decimal-digit:check0:
412
413 3d/compare-eax-with 0x30/imm32/0
414 7c/jump-if-< $to-decimal-digit:abort/disp8
415 $to-decimal-digit:check1:
416
417 3d/compare-eax-with 0x39/imm32/f
418 7f/jump-if-> $to-decimal-digit:abort/disp8
419 $to-decimal-digit:digit:
420
421 2d/subtract-from-eax 0x30/imm32/0
422 $to-decimal-digit:end:
423
424 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . .
425 5d/pop-to-ebp
426 c3/return
427
428 $to-decimal-digit:abort:
429
430
431 68/push "to-decimal-digit: not a digit character: "/imm32
432 68/push Stderr/imm32
433
434 e8/call write-buffered/disp32
435
436 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
437
438
439 50/push-eax
440 68/push Stderr/imm32
441
442
443 e8/call write-int32-hex-buffered/disp32
444
445 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
446
447
448 68/push Newline/imm32
449 68/push Stderr/imm32
450
451 e8/call write-buffered/disp32
452
453 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
454
455
456 68/push Stderr/imm32
457
458 e8/call flush/disp32
459
460 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
461
462 bb/copy-to-ebx 1/imm32
463 e8/call syscall_exit/disp32
464
465
466