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