https://github.com/akkartik/mu/blob/main/linux/factorial.subx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 == code
17
18
19
20
21 factorial:
22
23 55/push-ebp
24 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . .
25 51/push-ecx
26
27 b8/copy-to-eax 1/imm32
28 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 1/imm32
29 7e/jump-if-<= $factorial:end/disp8
30
31 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 .
32 49/decrement-ecx
33
34
35 51/push-ecx
36
37 e8/call factorial/disp32
38
39 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
40
41 f7 4/subop/multiply 1/mod/*+disp8 5/rm32/ebp . . 8/disp8 .
42
43 $factorial:end:
44
45 59/pop-to-ecx
46
47 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . .
48 5d/pop-to-ebp
49 c3/return
50
51 test-factorial:
52
53
54 68/push 5/imm32
55
56 e8/call factorial/disp32
57
58 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
59
60
61 68/push "F - test-factorial"/imm32
62 68/push 0x78/imm32/expected-120
63 50/push-eax
64
65 e8/call check-ints-equal/disp32
66
67 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32
68
69 c3/return
70
71 Entry:
72
73 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . .
74
75
76
77
78 68/push Heap/imm32
79 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Heap-size/disp32
80
81 e8/call new-segment/disp32
82
83 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
84
85
86 $run-main:
87 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 0/disp8 1/imm32
88 7f/jump-if-> $main:run-tests/disp8
89
90
91 68/push 5/imm32
92
93 e8/call factorial/disp32
94
95 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
96
97 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa/imm32
98 68/push 0xa/imm32/decimal-digits-in-32bit-number
99 68/push 0/imm32/read
100 68/push 0/imm32/write
101 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . .
102
103
104 50/push-eax
105 51/push-ecx
106
107 e8/call write-int32-decimal/disp32
108
109 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
110
111
112 51/push-ecx
113 68/push 2/imm32/stderr
114
115 e8/call write-stream/disp32
116
117 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
118
119
120 68/push Newline/imm32
121 68/push 2/imm32/stderr
122
123 e8/call write/disp32
124
125 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
126
127 89/copy 3/mod/direct 3/rm32/ebx . . . 0/r32/eax . .
128 eb/jump $main:end/disp8
129 $main:run-tests:
130
131
132
133
134 68/push "test"/imm32
135 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 .
136
137 e8/call kernel-string-equal?/disp32
138
139 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
140
141 3d/compare-eax-and 0/imm32/false
142 74/jump-if-= $main:do-nothing/disp8
143
144 e8/call run-tests/disp32
145
146 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/ebx Num-test-failures/disp32
147 eb/jump $main:end/disp8
148 $main:do-nothing:
149 bb/copy-to-ebx 0/imm32
150 $main:end:
151 e8/call syscall_exit/disp32
152
153