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