https://github.com/akkartik/mu/blob/master/apps/crenshaw2-1b.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
36
37 68/push Heap/imm32
38 68/push 0x10000/imm32/64KB
39
40 e8/call new-segment/disp32
41
42 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
43
44
45 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
46
47
48 81 7/subop/compare 1/mod/*+disp8 5/rm32/EBP . . . . 0/disp8 1/imm32
49 7e/jump-if-lesser-or-equal $run-main/disp8
50
51
52 68/push "test"/imm32
53 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 .
54
55 e8/call kernel-string-equal?/disp32
56
57 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
58
59 3d/compare-EAX-and 1/imm32
60 75/jump-if-not-equal $run-main/disp8
61
62 e8/call run-tests/disp32
63 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Num-test-failures/disp32
64 eb/jump $main:end/disp8
65 $run-main:
66
67
68 81 5/subop/subtract 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
69 89/copy 3/mod/direct 0/rm32/EAX . . . 4/r32/ESP . .
70
71
72 c7 0/subop/copy 0/mod/direct 0/rm32/EAX . . . . . 0/imm32
73
74
75 50/push-EAX/ed
76 68/push 2/imm32/stderr
77 68/push 1/imm32/stdout
78 68/push Stdin/imm32
79
80 e8/call compile/disp32
81
82 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32
83
84 bb/copy-to-EBX 0/imm32
85 $main:end:
86 b8/copy-to-EAX 1/imm32/exit
87 cd/syscall 0x80/imm8
88
89
90 compile:
91
92 55/push-EBP
93 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
94
95 50/push-EAX
96 51/push-ECX
97
98
99
100 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 .
101
102 e8/call get-char/disp32
103
104 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
105
106
107
108
109
110 81 5/subop/subtract 3/mod/direct 4/rm32/ESP . . . . . 0x13/imm32
111 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . .
112
113
114 c7 0/subop/copy 1/mod/*+disp8 1/rm32/ECX . . . . 8/disp8 7/imm32
115
116
117 51/push-ECX
118
119 e8/call clear-stream/disp32
120
121 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
122
123
124
125 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0x14/disp8 .
126 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0x10/disp8 .
127 51/push-ECX/num
128 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 .
129
130 e8/call get-num/disp32
131
132 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32
133
134
135
136
137
138
139
140 68/push "bb/copy-to-EBX "/imm32
141 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 .
142
143 e8/call write/disp32
144
145 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
146
147
148 51/push-ECX/num
149 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 .
150
151 e8/call write-stream/disp32
152
153 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
154
155
156 68/push Newline/imm32
157 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 .
158
159 e8/call write/disp32
160
161 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
162
163
164 68/push "b8/copy-to-EAX 1/imm32/exit\n"/imm32
165 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 .
166
167 e8/call write/disp32
168
169 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
170
171
172 68/push "cd/syscall 0x80/imm8\n"/imm32
173 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 .
174
175 e8/call write/disp32
176
177 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
178 $compile:end:
179
180 59/pop-to-ECX
181 58/pop-to-EAX
182
183 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . .
184 5d/pop-to-EBP
185 c3/return
186
187
188
189
190
191 get-num:
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217 55/push-EBP
218 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
219
220
221
222 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Look/disp32 .
223
224 e8/call is-digit?/disp32
225
226 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
227
228 3d/compare-EAX-and 0/imm32
229 75/jump-if-not-equal $get-num:main/disp8
230
231
232 68/push "integer"/imm32
233 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0x10/disp8 .
234 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0x14/disp8 .
235
236 e8/call expected/disp32
237
238 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32
239 $get-num:main:
240
241
242 50/push-EAX
243 51/push-ECX
244 52/push-EDX
245 53/push-EBX
246 56/push-ESI
247 57/push-EDI
248
249
250 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 8/disp8 .
251
252 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 7/r32/EDI 0xc/disp8 .
253
254 8b/copy 0/mod/indirect 7/rm32/EDI . . . 1/r32/ECX . .
255
256 8b/copy 1/mod/*+disp8 7/rm32/EDI . . . 2/r32/EDX 8/disp8 .
257 $get-num:loop:
258
259 39/compare 3/mod/direct 2/rm32/EDX . . . 1/r32/ECX . .
260 7d/jump-if-lesser $get-num:loop-stage2/disp8
261
262
263 68/push "get-num: too many digits in number"/imm32
264 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0x10/disp8 .
265 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0x14/disp8 .
266
267 e8/call error/disp32
268
269 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32
270 $get-num:loop-stage2:
271
272 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/EDI 1/index/ECX . 3/r32/EBX 0xc/disp8 .
273 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/EAX Look/disp32 .
274 88/copy-byte 0/mod/indirect 3/rm32/EBX . . . 0/r32/AL . .
275
276 41/increment-ECX
277
278
279 56/push-ESI
280
281 e8/call get-char/disp32
282
283 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
284
285
286
287 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Look/disp32 .
288
289 e8/call is-digit?/disp32
290
291 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
292
293 3d/compare-EAX-and 0/imm32
294 0f 85/jump-if-not-equal $get-num:loop/disp32
295 $get-num:loop-end:
296
297 89/copy 0/mod/indirect 7/rm32/EDI . . . 1/r32/ECX . .
298 $get-num:end:
299
300 5f/pop-to-EDI
301 5e/pop-to-ESI
302 5b/pop-to-EBX
303 5a/pop-to-EDX
304 59/pop-to-ECX
305 58/pop-to-EAX
306
307 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . .
308 5d/pop-to-EBP
309 c3/return
310
311 test-get-num-reads-single-digit:
312
313
314 55/push-EBP
315 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
316
317
318
319 68/push _test-stream/imm32
320
321 e8/call clear-stream/disp32
322
323 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
324
325
326 b8/copy-to-EAX _test-buffered-file/imm32
327 05/add-to-EAX 4/imm32
328 50/push-EAX
329
330 e8/call clear-stream/disp32
331
332 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
333
334
335 68/push _test-output-stream/imm32
336
337 e8/call clear-stream/disp32
338
339 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
340
341
342 68/push _test-error-stream/imm32
343
344 e8/call clear-stream/disp32
345
346 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
347
348
349
350 68/push "3"/imm32
351 68/push _test-stream/imm32
352
353 e8/call write/disp32
354
355 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
356
357
358 81 5/subop/subtract 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
359 89/copy 3/mod/direct 0/rm32/EAX . . . 4/r32/ESP . .
360
361
362 68/push 0x10/imm32/nbytes-of-args-for-get-num
363 50/push-EAX/ed
364
365 e8/call tailor-exit-descriptor/disp32
366
367 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
368
369
370
371 68/push _test-buffered-file/imm32
372
373 e8/call get-char/disp32
374
375 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
376
377
378 50/push-EAX/ed
379 68/push _test-error-stream/imm32
380 68/push _test-output-stream/imm32
381 68/push _test-buffered-file/imm32
382
383 e8/call get-num/disp32
384
385
386 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32
387
388
389 68/push "F - test-get-num-reads-single-digit"/imm32
390 68/push 0x33/imm32
391 b8/copy-to-EAX _test-output-stream/imm32
392 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 .
393
394 e8/call check-ints-equal/disp32
395
396 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32
397
398 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
399 5d/pop-to-EBP
400 c3/return
401
402 test-get-num-aborts-on-non-digit-in-Look:
403
404
405 55/push-EBP
406 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
407
408
409
410 68/push _test-stream/imm32
411
412 e8/call clear-stream/disp32
413
414 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
415
416
417 b8/copy-to-EAX _test-buffered-file/imm32
418 05/add-to-EAX 4/imm32
419 50/push-EAX
420
421 e8/call clear-stream/disp32
422
423 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
424
425
426 68/push _test-output-stream/imm32
427
428 e8/call clear-stream/disp32
429
430 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
431
432
433 68/push _test-error-stream/imm32
434
435 e8/call clear-stream/disp32
436
437 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
438
439
440
441 68/push "3"/imm32
442 68/push _test-stream/imm32
443
444 e8/call write/disp32
445
446 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
447
448
449 81 5/subop/subtract 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
450 89/copy 3/mod/direct 0/rm32/EAX . . . 4/r32/ESP . .
451
452
453 68/push 0x10/imm32/nbytes-of-args-for-get-num
454 50/push-EAX/ed
455
456 e8/call tailor-exit-descriptor/disp32
457
458 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
459
460
461
462 50/push-EAX/ed
463 68/push _test-error-stream/imm32
464 68/push _test-output-stream/imm32
465 68/push _test-buffered-file/imm32
466
467 e8/call get-num/disp32
468
469
470 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32
471
472
473
474 68/push "F - test-get-num-aborts-on-non-digit-in-Look"/imm32
475 68/push 2/imm32
476
477 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 .
478
479 e8/call check-ints-equal/disp32
480
481 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32
482
483 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
484 5d/pop-to-EBP
485 c3/return
486
487 test-get-num-reads-multiple-digits:
488
489
490 55/push-EBP
491 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
492
493
494
495 68/push _test-stream/imm32
496
497 e8/call clear-stream/disp32
498
499 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
500
501
502 b8/copy-to-EAX _test-buffered-file/imm32
503 05/add-to-EAX 4/imm32
504 50/push-EAX
505
506 e8/call clear-stream/disp32
507
508 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
509
510
511 68/push _test-output-stream/imm32
512
513 e8/call clear-stream/disp32
514
515 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
516
517
518 68/push _test-error-stream/imm32
519
520 e8/call clear-stream/disp32
521
522 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
523
524
525
526 68/push "3456"/imm32
527 68/push _test-stream/imm32
528
529 e8/call write/disp32
530
531 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
532
533
534 81 5/subop/subtract 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
535 89/copy 3/mod/direct 0/rm32/EAX . . . 4/r32/ESP . .
536
537
538 68/push 0x10/imm32/nbytes-of-args-for-get-num
539 50/push-EAX/ed
540
541 e8/call tailor-exit-descriptor/disp32
542
543 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
544
545
546
547 68/push _test-buffered-file/imm32
548
549 e8/call get-char/disp32
550
551 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
552
553
554 50/push-EAX/ed
555 68/push _test-error-stream/imm32
556 68/push _test-output-stream/imm32
557 68/push _test-buffered-file/imm32
558
559 e8/call get-num/disp32
560
561
562 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32
563
564
565 68/push "F - test-get-num-reads-multiple-digits"/imm32
566 68/push 0x36353433/imm32
567 b8/copy-to-EAX _test-output-stream/imm32
568 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 .
569
570 e8/call check-ints-equal/disp32
571
572 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32
573
574 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
575 5d/pop-to-EBP
576 c3/return
577
578 test-get-num-reads-multiple-digits-followed-by-nondigit:
579
580
581 55/push-EBP
582 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
583
584
585
586 68/push _test-stream/imm32
587
588 e8/call clear-stream/disp32
589
590 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
591
592
593 b8/copy-to-EAX _test-buffered-file/imm32
594 05/add-to-EAX 4/imm32
595 50/push-EAX
596
597 e8/call clear-stream/disp32
598
599 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
600
601
602 68/push _test-output-stream/imm32
603
604 e8/call clear-stream/disp32
605
606 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
607
608
609 68/push _test-error-stream/imm32
610
611 e8/call clear-stream/disp32
612
613 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
614
615
616
617 68/push "3456 x"/imm32
618 68/push _test-stream/imm32
619
620 e8/call write/disp32
621
622 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
623
624
625 81 5/subop/subtract 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
626 89/copy 3/mod/direct 0/rm32/EAX . . . 4/r32/ESP . .
627
628
629 68/push 0x10/imm32/nbytes-of-args-for-get-num
630 50/push-EAX/ed
631
632 e8/call tailor-exit-descriptor/disp32
633
634 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
635
636
637
638 68/push _test-buffered-file/imm32
639
640 e8/call get-char/disp32
641
642 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
643
644
645 50/push-EAX/ed
646 68/push _test-error-stream/imm32
647 68/push _test-output-stream/imm32
648 68/push _test-buffered-file/imm32
649
650 e8/call get-num/disp32
651
652
653 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32
654
655
656 68/push "F - test-get-num-reads-multiple-digits-followed-by-nondigit"/imm32
657 68/push 0x36353433/imm32
658 b8/copy-to-EAX _test-output-stream/imm32
659 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 .
660
661 e8/call check-ints-equal/disp32
662
663 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32
664
665 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
666 5d/pop-to-EBP
667 c3/return
668
669
670
671
672 expected:
673
674 55/push-EBP
675 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
676
677
678 68/push "Error: "/imm32
679 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 .
680
681 e8/call write/disp32
682
683 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
684
685
686 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0x10/disp8 .
687 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 .
688
689 e8/call write/disp32
690
691 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
692
693
694 68/push " expected\n"/imm32
695 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 .
696
697 e8/call write/disp32
698
699 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
700
701
702 68/push 1/imm32
703 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 .
704
705 e8/call stop/disp32
706
707 $expected:dead-end:
708
709 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . .
710 5d/pop-to-EBP
711 c3/return
712
713
714 get-char:
715
716 55/push-EBP
717 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
718
719 50/push-EAX
720
721
722 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 .
723
724 e8/call read-byte-buffered/disp32
725
726 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
727
728 89/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/EAX Look/disp32 .
729 $get-char:end:
730
731 58/pop-to-EAX
732
733 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . .
734 5d/pop-to-EBP
735 c3/return
736
737 is-digit?:
738
739 55/push-EBP
740 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
741
742 b8/copy-to-EAX 0/imm32
743
744 81 7/subop/compare 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 0x30/imm32
745 7c/jump-if-lesser $is-digit?:end/disp8
746
747 81 7/subop/compare 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 0x39/imm32
748 7f/jump-if-greater $is-digit?:end/disp8
749
750 b8/copy-to-EAX 1/imm32
751 $is-digit?:end:
752
753 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . .
754 5d/pop-to-EBP
755 c3/return
756
757 == data
758
759 Look:
760 0/imm32
761
762