https://github.com/akkartik/mu/blob/master/apps/mu.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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143 == data
144
145
146 Program:
147 0/imm32
148
149
150
151
152
153
154
155 Function-next:
156 0x10/imm32
157 Function-size:
158 0x14/imm32/20
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201 == code
202
203 Entry:
204
205 89/<- %ebp 4/r32/esp
206 (new-segment Heap-size Heap)
207
208 {
209
210 81 7/subop/compare *ebp 1/imm32
211 7e/jump-if-lesser-or-equal break/disp8
212
213 (kernel-string-equal? *(ebp+8) "test")
214 3d/compare-eax-and 0/imm32
215 74/jump-if-equal break/disp8
216
217 (run-tests)
218
219 8b/-> *Num-test-failures 3/r32/ebx
220 eb/jump $mu-main:end/disp8
221 }
222
223 (convert-mu Stdin Stdout)
224 (flush Stdout)
225
226 bb/copy-to-ebx 0/imm32
227 $mu-main:end:
228 b8/copy-to-eax 1/imm32/exit
229 cd/syscall 0x80/imm8
230
231 convert-mu:
232
233 55/push-ebp
234 89/<- %ebp 4/r32/esp
235
236 (parse-mu *(ebp+8))
237 (check-mu-types)
238 (emit-subx *(ebp+0xc))
239 $convert-mu:end:
240
241 89/<- %esp 5/r32/ebp
242 5d/pop-to-ebp
243 c3/return
244
245 test-convert-empty-input:
246
247
248 55/push-ebp
249 89/<- %ebp 4/r32/esp
250
251 (clear-stream _test-input-stream)
252 (clear-stream _test-input-buffered-file->buffer)
253 (clear-stream _test-output-stream)
254 (clear-stream _test-output-buffered-file->buffer)
255
256 (convert-mu _test-input-buffered-file _test-output-buffered-file)
257 (flush _test-output-buffered-file)
258 (check-stream-equal _test-output-stream "" "F - test-convert-empty-input")
259
260 89/<- %esp 5/r32/ebp
261 5d/pop-to-ebp
262 c3/return
263
264 test-convert-function-skeleton:
265
266
267
268
269
270
271
272
273
274
275
276
277
278 55/push-ebp
279 89/<- %ebp 4/r32/esp
280
281 (clear-stream _test-input-stream)
282 (clear-stream _test-input-buffered-file->buffer)
283 (clear-stream _test-output-stream)
284 (clear-stream _test-output-buffered-file->buffer)
285
286 (write _test-input-stream "fn foo {\n")
287 (write _test-input-stream "}\n")
288
289 (convert-mu _test-input-buffered-file _test-output-buffered-file)
290 (flush _test-output-buffered-file)
291 +-- 6 lines: #? # dump _test-output-stream --------------------------------------------------------------------------------------------------------------
297
298 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-skeleton/0")
299 (check-next-stream-line-equal _test-output-stream "# . prologue" "F - test-convert-function-skeleton/1")
300 (check-next-stream-line-equal _test-output-stream "55/push-ebp" "F - test-convert-function-skeleton/2")
301 (check-next-stream-line-equal _test-output-stream "89/<- %ebp 4/r32/esp" "F - test-convert-function-skeleton/3")
302 (check-next-stream-line-equal _test-output-stream "# . epilogue" "F - test-convert-function-skeleton/4")
303 (check-next-stream-line-equal _test-output-stream "89/<- %esp 5/r32/ebp" "F - test-convert-function-skeleton/5")
304 (check-next-stream-line-equal _test-output-stream "5d/pop-to-ebp" "F - test-convert-function-skeleton/6")
305 (check-next-stream-line-equal _test-output-stream "c3/return" "F - test-convert-function-skeleton/7")
306
307 89/<- %esp 5/r32/ebp
308 5d/pop-to-ebp
309 c3/return
310
311 test-convert-multiple-function-skeletons:
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335 55/push-ebp
336 89/<- %ebp 4/r32/esp
337
338 (clear-stream _test-input-stream)
339 (clear-stream _test-input-buffered-file->buffer)
340 (clear-stream _test-output-stream)
341 (clear-stream _test-output-buffered-file->buffer)
342
343 (write _test-input-stream "fn foo {\n")
344 (write _test-input-stream "}\n")
345 (write _test-input-stream "fn bar {\n")
346 (write _test-input-stream "}\n")
347
348 (convert-mu _test-input-buffered-file _test-output-buffered-file)
349 (flush _test-output-buffered-file)
350 +-- 6 lines: #? # dump _test-output-stream --------------------------------------------------------------------------------------------------------------
356
357 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-multiple-function-skeletons/0")
358 (check-next-stream-line-equal _test-output-stream "# . prologue" "F - test-convert-multiple-function-skeletons/1")
359 (check-next-stream-line-equal _test-output-stream "55/push-ebp" "F - test-convert-multiple-function-skeletons/2")
360 (check-next-stream-line-equal _test-output-stream "89/<- %ebp 4/r32/esp" "F - test-convert-multiple-function-skeletons/3")
361 (check-next-stream-line-equal _test-output-stream "# . epilogue" "F - test-convert-multiple-function-skeletons/4")
362 (check-next-stream-line-equal _test-output-stream "89/<- %esp 5/r32/ebp" "F - test-convert-multiple-function-skeletons/5")
363 (check-next-stream-line-equal _test-output-stream "5d/pop-to-ebp" "F - test-convert-multiple-function-skeletons/6")
364 (check-next-stream-line-equal _test-output-stream "c3/return" "F - test-convert-multiple-function-skeletons/7")
365
366 (check-next-stream-line-equal _test-output-stream "bar:" "F - test-convert-multiple-function-skeletons/10")
367 (check-next-stream-line-equal _test-output-stream "# . prologue" "F - test-convert-multiple-function-skeletons/11")
368 (check-next-stream-line-equal _test-output-stream "55/push-ebp" "F - test-convert-multiple-function-skeletons/12")
369 (check-next-stream-line-equal _test-output-stream "89/<- %ebp 4/r32/esp" "F - test-convert-multiple-function-skeletons/13")
370 (check-next-stream-line-equal _test-output-stream "# . epilogue" "F - test-convert-multiple-function-skeletons/14")
371 (check-next-stream-line-equal _test-output-stream "89/<- %esp 5/r32/ebp" "F - test-convert-multiple-function-skeletons/15")
372 (check-next-stream-line-equal _test-output-stream "5d/pop-to-ebp" "F - test-convert-multiple-function-skeletons/16")
373 (check-next-stream-line-equal _test-output-stream "c3/return" "F - test-convert-multiple-function-skeletons/17")
374
375 89/<- %esp 5/r32/ebp
376 5d/pop-to-ebp
377 c3/return
378
379 test-convert-function-with-arg:
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398 55/push-ebp
399 89/<- %ebp 4/r32/esp
400
401 (clear-stream _test-input-stream)
402 (clear-stream _test-input-buffered-file->buffer)
403 (clear-stream _test-output-stream)
404 (clear-stream _test-output-buffered-file->buffer)
405
406 (write _test-input-stream "fn foo {\n")
407 (write _test-input-stream "}\n")
408
409 (convert-mu _test-input-buffered-file _test-output-buffered-file)
410 (flush _test-output-buffered-file)
411 +-- 6 lines: #? # dump _test-output-stream --------------------------------------------------------------------------------------------------------------
417
418 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-skeleton/0")
419 (check-next-stream-line-equal _test-output-stream "# . prologue" "F - test-convert-function-skeleton/1")
420 (check-next-stream-line-equal _test-output-stream "55/push-ebp" "F - test-convert-function-skeleton/2")
421 (check-next-stream-line-equal _test-output-stream "89/<- %ebp 4/r32/esp" "F - test-convert-function-skeleton/3")
422 (check-next-stream-line-equal _test-output-stream "# . epilogue" "F - test-convert-function-skeleton/4")
423 (check-next-stream-line-equal _test-output-stream "89/<- %esp 5/r32/ebp" "F - test-convert-function-skeleton/5")
424 (check-next-stream-line-equal _test-output-stream "5d/pop-to-ebp" "F - test-convert-function-skeleton/6")
425 (check-next-stream-line-equal _test-output-stream "c3/return" "F - test-convert-function-skeleton/7")
426
427 89/<- %esp 5/r32/ebp
428 5d/pop-to-ebp
429 c3/return
430
431 parse-mu:
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455 55/push-ebp
456 89/<- %ebp 4/r32/esp
457
458 50/push-eax
459 51/push-ecx
460 52/push-edx
461 57/push-edi
462
463 81 5/subop/subtract %esp 0x200/imm32
464 68/push 0x200/imm32/length
465 68/push 0/imm32/read
466 68/push 0/imm32/write
467 89/<- %ecx 4/r32/esp
468
469 68/push 0/imm32/end
470 68/push 0/imm32/start
471 89/<- %edx 4/r32/esp
472
473 bf/copy-to-edi Program/imm32
474 {
475 $parse-mu:line-loop:
476 (clear-stream %ecx)
477 (read-line-buffered *(ebp+8) %ecx)
478
479 81 7/subop/compare *ecx 0/imm32
480 0f 84/jump-if-equal break/disp32
481 +-- 6 lines: #? # dump line ---------------------------------------------------------------------------------------------------------------------------
487 {
488 $parse-mu:word-loop:
489 (next-word-or-string %ecx %edx)
490
491 (slice-empty? %edx)
492 3d/compare-eax-and 0/imm32
493 0f 85/jump-if-not-equal break/disp32
494
495
496 8b/-> *edx 0/r32/eax
497 8a/copy-byte *eax 0/r32/AL
498 81 4/subop/and %eax 0xff/imm32
499
500 3d/compare-eax-and 0x23/imm32/hash
501 0f 84/jump-if-equal break/disp32
502
503 {
504 (slice-equal? %edx "fn")
505 3d/compare-eax-and 0/imm32
506 0f 84/jump-if-equal break/disp32
507
508 (allocate Heap *Function-size)
509 (populate-mu-function-header %ecx %eax)
510 (populate-mu-function-body *(ebp+8) %eax)
511
512 89/<- *edi 0/r32/eax
513
514 8d/address-> *(eax+0x10) 7/r32/edi
515 e9/jump $parse-mu:word-loop/disp32
516 }
517
518 e9/jump $parse-mu:abort/disp32
519 }
520 e9/jump loop/disp32
521 }
522 $parse-mu:end:
523
524 81 0/subop/add %esp 0x214/imm32
525
526 5f/pop-to-edi
527 5a/pop-to-edx
528 59/pop-to-ecx
529 58/pop-to-eax
530
531 89/<- %esp 5/r32/ebp
532 5d/pop-to-ebp
533 c3/return
534
535 $parse-mu:abort:
536
537 (write-buffered Stderr "unexpected top-level command: ")
538 (write-buffered Stderr %edx)
539 (write-buffered Stderr "\n")
540 (flush Stderr)
541
542 bb/copy-to-ebx 1/imm32
543 b8/copy-to-eax 1/imm32/exit
544 cd/syscall 0x80/imm8
545
546
547
548
549
550
551
552 populate-mu-function-header:
553
554 55/push-ebp
555 89/<- %ebp 4/r32/esp
556
557 50/push-eax
558 51/push-ecx
559 57/push-edi
560
561 8b/-> *(ebp+0xc) 7/r32/edi
562
563 68/push 0/imm32/end
564 68/push 0/imm32/start
565 89/<- %ecx 4/r32/esp
566
567 (next-word *(ebp+8) %ecx)
568 (slice-to-string Heap %ecx)
569 89/<- *edi 0/r32/eax
570
571 (next-word *(ebp+8) %ecx)
572 (slice-equal? %ecx "{")
573 3d/compare-eax-and 0/imm32
574 74/jump-if-equal $populate-mu-function-header:abort/disp8
575
576 {
577
578 (next-word *(ebp+8) %ecx)
579
580 (slice-empty? %ecx)
581 3d/compare-eax-and 0/imm32
582 75/jump-if-not-equal break/disp8
583
584
585 8b/-> *edx 0/r32/eax
586 8a/copy-byte *eax 0/r32/AL
587 81 4/subop/and %eax 0xff/imm32
588
589 3d/compare-eax-and 0x23/imm32/hash
590 74/jump-if-equal break/disp8
591
592 eb/jump $populate-mu-function-header:abort/disp8
593 }
594 $populate-mu-function-header:end:
595
596 81 0/subop/add %esp 8/imm32
597
598 5f/pop-to-edi
599 59/pop-to-ecx
600 58/pop-to-eax
601
602 89/<- %esp 5/r32/ebp
603 5d/pop-to-ebp
604 c3/return
605
606 $populate-mu-function-header:abort:
607
608 (write-buffered Stderr "function header not in form 'fn <name> {' -- '")
609 (rewind-stream *(ebp+8))
610 (write-stream 2 *(ebp+8))
611 (write-buffered Stderr "'\n")
612 (flush Stderr)
613
614 bb/copy-to-ebx 1/imm32
615 b8/copy-to-eax 1/imm32/exit
616 cd/syscall 0x80/imm8
617
618
619
620
621 populate-mu-function-body:
622
623 55/push-ebp
624 89/<- %ebp 4/r32/esp
625
626 50/push-eax
627 51/push-ecx
628 52/push-edx
629 53/push-ebx
630
631 81 5/subop/subtract %esp 0x200/imm32
632 68/push 0x200/imm32/length
633 68/push 0/imm32/read
634 68/push 0/imm32/write
635 89/<- %ecx 4/r32/esp
636
637 68/push 0/imm32/end
638 68/push 0/imm32/start
639 89/<- %edx 4/r32/esp
640
641 bb/copy-to-ebx 1/imm32
642 {
643 $populate-mu-function-body:line-loop:
644
645 81 7/subop/compare %ebx 0/imm32
646 0f 84/jump-if-equal break/disp32
647
648 (clear-stream %ecx)
649 (read-line-buffered *(ebp+8) %ecx)
650
651 81 7/subop/compare *ecx 0/imm32
652 0f 84/jump-if-equal break/disp32
653
654 (next-word %ecx %edx)
655
656 (slice-empty? %ecx)
657 3d/compare-eax-and 0/imm32
658 75/jump-if-not-equal loop/disp8
659
660
661 8b/-> *edx 0/r32/eax
662 8a/copy-byte *eax 0/r32/AL
663 81 4/subop/and %eax 0xff/imm32
664
665 3d/compare-eax-and 0x23/imm32/hash
666 74/jump-if-equal loop/disp8
667 {
668
669 {
670 (slice-equal? %ecx "{")
671 3d/compare-eax-and 0/imm32
672 74/jump-if-equal break/disp8
673 43/increment-ebx
674 eb/jump $curly-found:end/disp8
675 }
676
677 {
678 (slice-equal? %ecx "}")
679 3d/compare-eax-and 0/imm32
680 74/jump-if-equal break/disp8
681 4b/decrement-ebx
682 eb/jump $curly-found:end/disp8
683 }
684
685 eb/jump $populate-mu-function-body:end/disp8
686 }
687
688 $curly-found:end:
689
690 (next-word %ecx %edx)
691
692 (slice-empty? %ecx)
693 3d/compare-eax-and 0/imm32
694 0f 85/jump-if-not-equal loop/disp32
695
696
697 8b/-> *edx 0/r32/eax
698 8a/copy-byte *eax 0/r32/AL
699 81 4/subop/and %eax 0xff/imm32
700
701 3d/compare-eax-and 0x23/imm32/hash
702 0f 84/jump-if-equal loop/disp32
703
704 eb/jump $populate-mu-function-body:abort/disp8
705 }
706 $populate-mu-function-body:end:
707
708 81 0/subop/add %esp 0x214/imm32
709
710 5b/pop-to-ebx
711 5a/pop-to-edx
712 59/pop-to-ecx
713 58/pop-to-eax
714
715 89/<- %esp 5/r32/ebp
716 5d/pop-to-ebp
717 c3/return
718
719 $populate-mu-function-body:abort:
720
721 (write-buffered Stderr "'{' or '}' should be on its own line, but got '")
722 (rewind-stream %ecx)
723 (write-stream 2 %ecx)
724 (write-buffered Stderr "'\n")
725 (flush Stderr)
726
727 bb/copy-to-ebx 1/imm32
728 b8/copy-to-eax 1/imm32/exit
729 cd/syscall 0x80/imm8
730
731
732 check-mu-types:
733
734 55/push-ebp
735 89/<- %ebp 4/r32/esp
736
737 $check-types:end:
738
739 89/<- %esp 5/r32/ebp
740 5d/pop-to-ebp
741 c3/return
742
743 emit-subx:
744
745 55/push-ebp
746 89/<- %ebp 4/r32/esp
747
748 50/push-eax
749 51/push-ecx
750 57/push-edi
751
752 8b/-> *(ebp+8) 7/r32/edi
753
754 8b/-> *Program 1/r32/ecx
755 {
756
757 81 7/subop/compare %ecx 0/imm32
758 0f 84/jump-if-equal break/disp32
759 (emit-subx-function %edi %ecx)
760
761 8b/-> *(ecx+0x10) 1/r32/ecx
762 e9/jump loop/disp32
763 }
764 $emit-subx:end:
765
766 5f/pop-to-edi
767 59/pop-to-ecx
768 58/pop-to-eax
769
770 89/<- %esp 5/r32/ebp
771 5d/pop-to-ebp
772 c3/return
773
774
775
776
777
778
779
780 emit-subx-function:
781
782 55/push-ebp
783 89/<- %ebp 4/r32/esp
784
785 50/push-eax
786 51/push-ecx
787 57/push-edi
788
789 8b/-> *(ebp+8) 7/r32/edi
790
791 8b/-> *(ebp+0xc) 1/r32/ecx
792
793 (write-buffered %edi *ecx)
794 (write-buffered %edi ":\n")
795 (emit-subx-prologue %edi)
796 (emit-subx-block %edi *(ecx+4))
797 (emit-subx-epilogue %edi)
798 $emit-subx-function:end:
799
800 5f/pop-to-edi
801 59/pop-to-ecx
802 58/pop-to-eax
803
804 89/<- %esp 5/r32/ebp
805 5d/pop-to-ebp
806 c3/return
807
808 emit-subx-block:
809
810 55/push-ebp
811 89/<- %ebp 4/r32/esp
812
813 $emit-subx-block:end:
814
815 89/<- %esp 5/r32/ebp
816 5d/pop-to-ebp
817 c3/return
818
819 emit-subx-statement:
820
821 55/push-ebp
822 89/<- %ebp 4/r32/esp
823
824 50/push-eax
825 51/push-ecx
826
827 8b/-> *(ebp+0x18) 1/r32/ecx
828 {
829
830 81 7/subop/compare *(ebp+0xc) 0/imm32
831 0f 84/jump-if-equal $emit-subx-statement:abort/disp32
832
833 (mu-stmt-matches-primitive? *(ebp+0xc) %ecx)
834 3d/compare-eax-and 0/imm32
835 75/jump-if-not-equal break/disp8
836
837
838 8b/-> *(ecx+0x10) 1/r32/ecx
839 e9/jump loop/disp32
840 }
841 $emit-subx-statement:end:
842
843 59/pop-to-ecx
844 58/pop-to-eax
845
846 89/<- %esp 5/r32/ebp
847 5d/pop-to-ebp
848 c3/return
849
850 $emit-subx-statement:abort:
851
852 (write-buffered Stderr "couldn't translate '")
853
854 (write-buffered Stderr "'\n")
855 (flush Stderr)
856
857 bb/copy-to-ebx 1/imm32
858 b8/copy-to-eax 1/imm32/exit
859 cd/syscall 0x80/imm8
860
861
862 mu-stmt-matches-primitive?:
863
864 55/push-ebp
865 89/<- %ebp 4/r32/esp
866
867 51/push-ecx
868
869 8b/-> *(ebp+8) 1/r32/ecx
870 8b/-> *(ebp+0xc) 0/r32/eax
871 (string-equal? *ecx *eax)
872 $mu-stmt-matches-primitive?:end:
873
874 59/pop-to-ecx
875
876 89/<- %esp 5/r32/ebp
877 5d/pop-to-ebp
878 c3/return
879
880 test-emit-subx-statement-primitive:
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903 55/push-ebp
904 89/<- %ebp 4/r32/esp
905
906 (clear-stream _test-output-stream)
907 (clear-stream _test-output-buffered-file->buffer)
908
909 68/push 0/imm32/next
910 68/push -8/imm32/stack-offset
911 68/push 0/imm32/int
912 68/push "foo"/imm32
913 89/<- %ecx 4/r32/esp
914
915 68/push 0/imm32/next
916 51/push-ecx/var-foo
917 89/<- %edx 4/r32/esp
918
919 68/push 0/imm32/next
920 68/push 0/imm32/outputs
921 52/push-edx/operand
922 68/push "increment"/imm32/operation
923 89/<- %edx 4/r32/esp
924
925 68/push 0/imm32/next
926 68/push "ff 0/subop/increment"/imm32
927 68/push 0/imm32/type-int
928 68/push 0/imm32/storage-memory
929 68/push "increment"/imm32/name
930 89/<- %ebx 4/r32/esp
931
932 (emit-subx-statement _test-output-buffered-file %edx %ecx 0 %ebx 0)
933 (flush _test-output-buffered-file)
934 +-- 6 lines: #? # dump _test-output-stream --------------------------------------------------------------------------------------------------------------
940
941 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment *(ebp-8)" "F - test-emit-subx-statement-primitive/0")
942
943 81 0/subop/add %esp 0x3c/imm32
944
945 89/<- %esp 5/r32/ebp
946 5d/pop-to-ebp
947 c3/return
948
949 test-emit-subx-statement-function-call:
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973 55/push-ebp
974 89/<- %ebp 4/r32/esp
975
976 (clear-stream _test-output-stream)
977 (clear-stream _test-output-buffered-file->buffer)
978
979 68/push 0/imm32/next
980 68/push -8/imm32/stack-offset
981 68/push 0/imm32/int
982 68/push "var"/imm32
983 89/<- %ecx 4/r32/esp
984
985 68/push 0/imm32/next
986 51/push-ecx/var
987 89/<- %edx 4/r32/esp
988
989 68/push 0/imm32/next
990 68/push 0/imm32/outputs
991 52/push-edx/operand
992 68/push "f"/imm32/operation
993 89/<- %edx 4/r32/esp
994
995 68/push 0/imm32/next
996 68/push "f2"/imm32
997 68/push 0/imm32/type-int
998 68/push 0/imm32/storage-memory
999 68/push "f"/imm32/name
1000 89/<- %ebx 4/r32/esp
1001
1002 (emit-subx-statement _test-output-buffered-file %edx %ecx 0 0 %ebx)
1003 (flush _test-output-buffered-file)
1004 +-- 6 lines: #? # dump _test-output-stream --------------------------------------------------------------------------------------------------------------
1010
1011 (check-next-stream-line-equal _test-output-stream "f2 *(ebp-8)" "F - test-emit-subx-statement-function-call/0")
1012
1013 81 0/subop/add %esp 0x3c/imm32
1014
1015 89/<- %esp 5/r32/ebp
1016 5d/pop-to-ebp
1017 c3/return
1018
1019 emit-subx-prologue:
1020
1021 55/push-ebp
1022 89/<- %ebp 4/r32/esp
1023
1024 (write-buffered *(ebp+8) "# . prologue\n")
1025 (write-buffered *(ebp+8) "55/push-ebp\n")
1026 (write-buffered *(ebp+8) "89/<- %ebp 4/r32/esp\n")
1027 $emit-subx-prologue:end:
1028
1029 89/<- %esp 5/r32/ebp
1030 5d/pop-to-ebp
1031 c3/return
1032
1033 emit-subx-epilogue:
1034
1035 55/push-ebp
1036 89/<- %ebp 4/r32/esp
1037
1038 (write-buffered *(ebp+8) "# . epilogue\n")
1039 (write-buffered *(ebp+8) "89/<- %esp 5/r32/ebp\n")
1040 (write-buffered *(ebp+8) "5d/pop-to-ebp\n")
1041 (write-buffered *(ebp+8) "c3/return\n")
1042 $emit-subx-epilogue:end:
1043
1044 89/<- %esp 5/r32/ebp
1045 5d/pop-to-ebp
1046 c3/return