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
227 55/push-EBP
228 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
229
230
231
232 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Look/disp32 .
233
234 e8/call is-digit?/disp32
235
236 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
237
238 3d/compare-EAX 0/imm32
239 75/jump-if-not-equal $get-num:main/disp8
240
241
242 68/push "integer"/imm32
243 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0x10/disp8 .
244 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0x14/disp8 .
245
246 e8/call expected/disp32
247
248 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32
249 $get-num:main:
250
251
252 50/push-EAX
253 51/push-ECX
254 52/push-EDX
255 53/push-EBX
256 56/push-ESI
257 57/push-EDI
258
259
260 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 8/disp8 .
261
262 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 7/r32/EDI 0xc/disp8 .
263
264 8b/copy 0/mod/indirect 7/rm32/EDI . . . 1/r32/ECX . .
265
266 8b/copy 1/mod/*+disp8 7/rm32/EDI . . . 2/r32/EDX 8/disp8 .
267 $get-num:loop:
268
269 39/compare 3/mod/direct 2/rm32/EDX . . . 1/r32/ECX . .
270 7d/jump-if-lesser $get-num:loop-stage2/disp8
271
272
273 68/push "get-num: too many digits in number"/imm32
274 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0x10/disp8 .
275 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0x14/disp8 .
276
277 e8/call error/disp32
278
279 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32
280 $get-num:loop-stage2:
281
282 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/EDI 1/index/ECX . 3/r32/EBX 0xc/disp8 .
283 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/EAX Look/disp32 .
284 88/copy-byte 0/mod/indirect 3/rm32/EBX . . . 0/r32/AL . .
285
286 41/increment-ECX
287
288
289 56/push-ESI
290
291 e8/call get-char/disp32
292
293 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
294
295
296
297 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Look/disp32 .
298
299 e8/call is-digit?/disp32
300
301 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
302
303 3d/compare-EAX 0/imm32
304 0f 85/jump-if-not-equal $get-num:loop/disp32
305 $get-num:loop-end:
306
307 89/copy 0/mod/indirect 7/rm32/EDI . . . 1/r32/ECX . .
308 $get-num:end:
309
310 5f/pop-to-EDI
311 5e/pop-to-ESI
312 5b/pop-to-EBX
313 5a/pop-to-EDX
314 59/pop-to-ECX
315 58/pop-to-EAX
316
317 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . .
318 5d/pop-to-EBP
319 c3/return
320
321 test-get-num-reads-single-digit:
322
323
324 55/push-EBP
325 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
326
327
328
329 68/push _test-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 b8/copy-to-EAX _test-buffered-file/imm32
337 05/add-to-EAX 4/imm32
338 50/push-EAX
339
340 e8/call clear-stream/disp32
341
342 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
343
344
345 68/push _test-output-stream/imm32
346
347 e8/call clear-stream/disp32
348
349 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
350
351
352 68/push _test-error-stream/imm32
353
354 e8/call clear-stream/disp32
355
356 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
357
358
359
360 68/push "3"/imm32
361 68/push _test-stream/imm32
362
363 e8/call write/disp32
364
365 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
366
367
368 81 5/subop/subtract 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
369 89/copy 3/mod/direct 0/rm32/EAX . . . 4/r32/ESP . .
370
371
372 68/push 0x10/imm32/nbytes-of-args-for-get-num
373 50/push-EAX/ed
374
375 e8/call tailor-exit-descriptor/disp32
376
377 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
378
379
380
381 68/push _test-buffered-file/imm32
382
383 e8/call get-char/disp32
384
385 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
386
387
388 50/push-EAX/ed
389 68/push _test-error-stream/imm32
390 68/push _test-output-stream/imm32
391 68/push _test-buffered-file/imm32
392
393 e8/call get-num/disp32
394
395
396 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32
397
398
399 68/push "F - test-get-num-reads-single-digit"/imm32
400 68/push 0x33/imm32
401 b8/copy-to-EAX _test-output-stream/imm32
402 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 .
403
404 e8/call check-ints-equal/disp32
405
406 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32
407
408 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
409 5d/pop-to-EBP
410 c3/return
411
412 test-get-num-aborts-on-non-digit-in-Look:
413
414
415 55/push-EBP
416 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
417
418
419
420 68/push _test-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 b8/copy-to-EAX _test-buffered-file/imm32
428 05/add-to-EAX 4/imm32
429 50/push-EAX
430
431 e8/call clear-stream/disp32
432
433 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
434
435
436 68/push _test-output-stream/imm32
437
438 e8/call clear-stream/disp32
439
440 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
441
442
443 68/push _test-error-stream/imm32
444
445 e8/call clear-stream/disp32
446
447 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
448
449
450
451 68/push "3"/imm32
452 68/push _test-stream/imm32
453
454 e8/call write/disp32
455
456 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
457
458
459 81 5/subop/subtract 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
460 89/copy 3/mod/direct 0/rm32/EAX . . . 4/r32/ESP . .
461
462
463 68/push 0x10/imm32/nbytes-of-args-for-get-num
464 50/push-EAX/ed
465
466 e8/call tailor-exit-descriptor/disp32
467
468 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
469
470
471
472 50/push-EAX/ed
473 68/push _test-error-stream/imm32
474 68/push _test-output-stream/imm32
475 68/push _test-buffered-file/imm32
476
477 e8/call get-num/disp32
478
479
480 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32
481
482
483
484 68/push "F - test-get-num-aborts-on-non-digit-in-Look"/imm32
485 68/push 2/imm32
486
487 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 .
488
489 e8/call check-ints-equal/disp32
490
491 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32
492
493 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
494 5d/pop-to-EBP
495 c3/return
496
497 test-get-num-reads-multiple-digits:
498
499
500 55/push-EBP
501 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
502
503
504
505 68/push _test-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 b8/copy-to-EAX _test-buffered-file/imm32
513 05/add-to-EAX 4/imm32
514 50/push-EAX
515
516 e8/call clear-stream/disp32
517
518 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
519
520
521 68/push _test-output-stream/imm32
522
523 e8/call clear-stream/disp32
524
525 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
526
527
528 68/push _test-error-stream/imm32
529
530 e8/call clear-stream/disp32
531
532 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
533
534
535
536 68/push "3456"/imm32
537 68/push _test-stream/imm32
538
539 e8/call write/disp32
540
541 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
542
543
544 81 5/subop/subtract 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
545 89/copy 3/mod/direct 0/rm32/EAX . . . 4/r32/ESP . .
546
547
548 68/push 0x10/imm32/nbytes-of-args-for-get-num
549 50/push-EAX/ed
550
551 e8/call tailor-exit-descriptor/disp32
552
553 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
554
555
556
557 68/push _test-buffered-file/imm32
558
559 e8/call get-char/disp32
560
561 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
562
563
564 50/push-EAX/ed
565 68/push _test-error-stream/imm32
566 68/push _test-output-stream/imm32
567 68/push _test-buffered-file/imm32
568
569 e8/call get-num/disp32
570
571
572 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32
573
574
575 68/push "F - test-get-num-reads-multiple-digits"/imm32
576 68/push 0x36353433/imm32
577 b8/copy-to-EAX _test-output-stream/imm32
578 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 .
579
580 e8/call check-ints-equal/disp32
581
582 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32
583
584 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
585 5d/pop-to-EBP
586 c3/return
587
588 test-get-num-reads-multiple-digits-followed-by-nondigit:
589
590
591 55/push-EBP
592 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
593
594
595
596 68/push _test-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 b8/copy-to-EAX _test-buffered-file/imm32
604 05/add-to-EAX 4/imm32
605 50/push-EAX
606
607 e8/call clear-stream/disp32
608
609 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
610
611
612 68/push _test-output-stream/imm32
613
614 e8/call clear-stream/disp32
615
616 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
617
618
619 68/push _test-error-stream/imm32
620
621 e8/call clear-stream/disp32
622
623 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
624
625
626
627 68/push "3456 x"/imm32
628 68/push _test-stream/imm32
629
630 e8/call write/disp32
631
632 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
633
634
635 81 5/subop/subtract 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
636 89/copy 3/mod/direct 0/rm32/EAX . . . 4/r32/ESP . .
637
638
639 68/push 0x10/imm32/nbytes-of-args-for-get-num
640 50/push-EAX/ed
641
642 e8/call tailor-exit-descriptor/disp32
643
644 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
645
646
647
648 68/push _test-buffered-file/imm32
649
650 e8/call get-char/disp32
651
652 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
653
654
655 50/push-EAX/ed
656 68/push _test-error-stream/imm32
657 68/push _test-output-stream/imm32
658 68/push _test-buffered-file/imm32
659
660 e8/call get-num/disp32
661
662
663 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32
664
665
666 68/push "F - test-get-num-reads-multiple-digits-followed-by-nondigit"/imm32
667 68/push 0x36353433/imm32
668 b8/copy-to-EAX _test-output-stream/imm32
669 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 .
670
671 e8/call check-ints-equal/disp32
672
673 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32
674
675 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
676 5d/pop-to-EBP
677 c3/return
678
679
680
681
682 expected:
683
684 55/push-EBP
685 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
686
687
688 68/push "Error: "/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 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0x10/disp8 .
697 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 .
698
699 e8/call write/disp32
700
701 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
702
703
704 68/push " expected"/imm32
705 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 .
706
707 e8/call write/disp32
708
709 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
710
711
712 68/push Newline/imm32
713 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 .
714
715 e8/call write/disp32
716
717 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
718
719
720 68/push 1/imm32
721 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 .
722
723 e8/call stop/disp32
724
725
726 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . .
727 5d/pop-to-EBP
728 c3/return
729
730
731 get-char:
732
733 55/push-EBP
734 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
735
736 50/push-EAX
737
738
739 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 .
740
741 e8/call read-byte/disp32
742
743 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
744
745 89/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/EAX Look/disp32 .
746
747 58/pop-to-EAX
748
749 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . .
750 5d/pop-to-EBP
751 c3/return
752
753 is-digit?:
754
755 55/push-EBP
756 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
757
758 b8/copy-to-EAX 0/imm32
759
760 81 7/subop/compare 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 0x30/imm32
761 7c/jump-if-lesser $is-digit?:end/disp8
762
763 81 7/subop/compare 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 0x39/imm32
764 7f/jump-if-greater $is-digit?:end/disp8
765
766 b8/copy-to-EAX 1/imm32
767 $is-digit?:end:
768
769 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . .
770 5d/pop-to-EBP
771 c3/return
772
773 == data
774
775 Look:
776 00 00 00 00
777
778 _test-output-stream:
779
780 00 00 00 00
781
782 00 00 00 00
783
784 08 00 00 00
785
786 00 00 00 00 00 00 00 00
787
788 _test-error-stream:
789
790 00 00 00 00
791
792 00 00 00 00
793
794 08 00 00 00
795
796 00 00 00 00 00 00 00 00
797
798