https://github.com/akkartik/mu/blob/main/apps/crenshaw2-1.subx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 == code
29
30
31
32
33 Entry:
34
35 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . .
36
37
38
39
40 68/push Heap/imm32
41 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Heap-size/disp32
42
43 e8/call new-segment/disp32
44
45 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
46
47
48
49 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 0/disp8 1/imm32
50 7e/jump-if-<= $run-main/disp8
51
52
53
54 68/push "test"/imm32
55 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 .
56
57 e8/call kernel-string-equal?/disp32
58
59 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
60
61 3d/compare-eax-and 0/imm32/false
62 74/jump-if-= $run-main/disp8
63
64 e8/call run-tests/disp32
65
66 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/ebx Num-test-failures/disp32
67 eb/jump $main:end/disp8
68 $run-main:
69
70
71
72 68/push 0/imm32/exit-descriptor
73 68/push 2/imm32/stderr
74 68/push 1/imm32/stdout
75 68/push Stdin/imm32
76
77 e8/call compile/disp32
78
79 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32
80
81 bb/copy-to-ebx 0/imm32
82 $main:end:
83 e8/call syscall_exit/disp32
84
85
86 compile:
87
88 55/push-ebp
89 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . .
90
91 50/push-eax
92 51/push-ecx
93
94
95
96 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 .
97
98 e8/call get-char/disp32
99
100 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
101
102
103
104
105
106 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x13/imm32
107 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . .
108
109
110 c7 0/subop/copy 1/mod/*+disp8 1/rm32/ecx . . . . 8/disp8 7/imm32
111
112
113 51/push-ecx
114
115 e8/call clear-stream/disp32
116
117 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
118
119
120
121 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x14/disp8 .
122 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 .
123 51/push-ecx/num
124 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 .
125
126 e8/call get-num/disp32
127
128 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32
129
130
131
132
133
134
135
136 68/push "bb/copy-to-ebx "/imm32
137 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 .
138
139 e8/call write/disp32
140
141 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
142
143
144 51/push-ecx/num
145 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 .
146
147 e8/call write-stream/disp32
148
149 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
150
151
152 68/push Newline/imm32
153 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 .
154
155 e8/call write/disp32
156
157 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
158
159
160 68/push "b8/copy-to-eax 1/imm32/exit\n"/imm32
161 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 .
162
163 e8/call write/disp32
164
165 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
166
167
168 68/push "cd/syscall 0x80/imm8\n"/imm32
169 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 .
170
171 e8/call write/disp32
172
173 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
174 $compile:end:
175
176 59/pop-to-ecx
177 58/pop-to-eax
178
179 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . .
180 5d/pop-to-ebp
181 c3/return
182
183
184
185
186
187 get-num:
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208 55/push-ebp
209 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . .
210
211
212
213 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Look/disp32 .
214
215 e8/call is-digit?/disp32
216
217 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
218
219 3d/compare-eax-and 0/imm32/false
220 75/jump-if-!= $get-num:main/disp8
221
222
223 68/push "integer"/imm32
224 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 .
225 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x14/disp8 .
226
227 e8/call expected/disp32
228
229 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32
230 $get-num:main:
231
232
233 50/push-eax
234 51/push-ecx
235 52/push-edx
236 53/push-ebx
237 56/push-esi
238 57/push-edi
239
240
241 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 .
242
243 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 .
244
245 8b/copy 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . .
246
247 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 8/disp8 .
248 $get-num:loop:
249
250 39/compare 3/mod/direct 2/rm32/edx . . . 1/r32/ecx . .
251 7d/jump-if-< $get-num:stage2/disp8
252
253
254 68/push "get-num: too many digits in number"/imm32
255 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 .
256 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x14/disp8 .
257
258 e8/call error/disp32
259
260 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32
261 $get-num:stage2:
262
263 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/edi 1/index/ecx . 3/r32/ebx 0xc/disp8 .
264 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/eax Look/disp32 .
265 88/copy-byte 0/mod/indirect 3/rm32/ebx . . . 0/r32/AL . .
266
267 41/increment-ecx
268
269
270 56/push-esi
271
272 e8/call get-char/disp32
273
274 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
275 $get-num:loop-end:
276
277 89/copy 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . .
278 $get-num:end:
279
280 5f/pop-to-edi
281 5e/pop-to-esi
282 5b/pop-to-ebx
283 5a/pop-to-edx
284 59/pop-to-ecx
285 58/pop-to-eax
286
287 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . .
288 5d/pop-to-ebp
289 c3/return
290
291 test-get-num-reads-single-digit:
292
293
294 55/push-ebp
295 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . .
296
297
298
299 68/push _test-stream/imm32
300
301 e8/call clear-stream/disp32
302
303 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
304
305
306 68/push $_test-buffered-file->buffer/imm32
307
308 e8/call clear-stream/disp32
309
310 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
311
312
313 68/push _test-output-stream/imm32
314
315 e8/call clear-stream/disp32
316
317 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
318
319
320 68/push _test-error-stream/imm32
321
322 e8/call clear-stream/disp32
323
324 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
325
326
327
328 68/push "3"/imm32
329 68/push _test-stream/imm32
330
331 e8/call write/disp32
332
333 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
334
335
336 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32
337 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . .
338
339
340 68/push 0x10/imm32/nbytes-of-args-for-get-num
341 50/push-eax/ed
342
343 e8/call tailor-exit-descriptor/disp32
344
345 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
346
347
348
349 68/push _test-buffered-file/imm32
350
351 e8/call get-char/disp32
352
353 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
354
355
356 50/push-eax/ed
357 68/push _test-error-stream/imm32
358 68/push _test-output-stream/imm32
359 68/push _test-buffered-file/imm32
360
361 e8/call get-num/disp32
362
363
364 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32
365
366
367 68/push "F - test-get-num-reads-single-digit"/imm32
368 68/push 0x33/imm32
369 b8/copy-to-eax _test-output-stream/imm32
370 ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 0xc/disp8 .
371
372 e8/call check-ints-equal/disp32
373
374 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32
375
376 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
377 5d/pop-to-ebp
378 c3/return
379
380 test-get-num-aborts-on-non-digit-in-Look:
381
382
383 55/push-ebp
384 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . .
385
386
387
388 68/push _test-stream/imm32
389
390 e8/call clear-stream/disp32
391
392 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
393
394
395 68/push $_test-buffered-file->buffer/imm32
396
397 e8/call clear-stream/disp32
398
399 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
400
401
402 68/push _test-output-stream/imm32
403
404 e8/call clear-stream/disp32
405
406 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
407
408
409 68/push _test-error-stream/imm32
410
411 e8/call clear-stream/disp32
412
413 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
414
415
416
417 68/push "3"/imm32
418 68/push _test-stream/imm32
419
420 e8/call write/disp32
421
422 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
423
424
425 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32
426 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . .
427
428
429 68/push 0x10/imm32/nbytes-of-args-for-get-num
430 50/push-eax/ed
431
432 e8/call tailor-exit-descriptor/disp32
433
434 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
435
436
437
438 50/push-eax/ed
439 68/push _test-error-stream/imm32
440 68/push _test-output-stream/imm32
441 68/push _test-buffered-file/imm32
442
443 e8/call get-num/disp32
444
445
446 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32
447
448
449
450 68/push "F - test-get-num-aborts-on-non-digit-in-Look"/imm32
451 68/push 2/imm32
452
453 ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 .
454
455 e8/call check-ints-equal/disp32
456
457 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32
458
459 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
460 5d/pop-to-ebp
461 c3/return
462
463
464
465
466 expected:
467
468 55/push-ebp
469 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . .
470
471
472 68/push "Error: "/imm32
473 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 .
474
475 e8/call write/disp32
476
477 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
478
479
480 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 .
481 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 .
482
483 e8/call write/disp32
484
485 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
486
487
488 68/push " expected\n"/imm32
489 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 .
490
491 e8/call write/disp32
492
493 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
494
495
496 68/push 1/imm32
497 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 .
498
499 e8/call stop/disp32
500
501 $expected:dead-end:
502
503 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . .
504 5d/pop-to-ebp
505 c3/return
506
507
508 get-char:
509
510 55/push-ebp
511 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . .
512
513 50/push-eax
514
515
516 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 .
517
518 e8/call read-byte-buffered/disp32
519
520 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
521
522 89/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/eax Look/disp32 .
523 $get-char:end:
524
525 58/pop-to-eax
526
527 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . .
528 5d/pop-to-ebp
529 c3/return
530
531 is-digit?:
532
533 55/push-ebp
534 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . .
535
536 b8/copy-to-eax 0/imm32
537
538 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 0x30/imm32
539 7c/jump-if-< $is-digit?:end/disp8
540
541 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 0x39/imm32
542 7f/jump-if-> $is-digit?:end/disp8
543
544 b8/copy-to-eax 1/imm32
545 $is-digit?:end:
546
547 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . .
548 5d/pop-to-ebp
549 c3/return
550
551 == data
552
553 Look:
554 0/imm32
555
556