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