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 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"/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 Newline/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
174
175 68/push "cd/syscall 0x80/imm8"/imm32
176 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 .
177
178 e8/call write/disp32
179
180 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
181
182
183 68/push Newline/imm32
184 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 .
185
186 e8/call write/disp32
187
188 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
189 $compile:end:
190
191 59/pop-to-ECX
192 58/pop-to-EAX
193
194 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . .
195 5d/pop-to-EBP
196 c3/return
197
198
199
200
201
202 get-num:
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 0/imm32
777
778 _test-output-stream:
779
780 0/imm32
781
782 0/imm32
783
784 8/imm32
785
786 00 00 00 00 00 00 00 00
787
788 _test-error-stream:
789
790 0/imm32
791
792 0/imm32
793
794 8/imm32
795
796 00 00 00 00 00 00 00 00
797
798