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