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