https://github.com/akkartik/mu/blob/main/linux/braces.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 == code
52
53 Entry:
54
55 89/<- %ebp 4/r32/esp
56
57 (new-segment *Heap-size Heap)
58
59 81 7/subop/compare *ebp 1/imm32
60 7e/jump-if-<= $subx-braces-main:interactive/disp8
61
62 (kernel-string-equal? *(ebp+8) "test")
63 3d/compare-eax-and 0/imm32/false
64 74/jump-if-= $subx-braces-main:interactive/disp8
65
66 (run-tests)
67
68 8b/-> *Num-test-failures 3/r32/ebx
69 eb/jump $subx-braces-main:end/disp8
70 $subx-braces-main:interactive:
71 (subx-braces Stdin Stdout)
72
73 bb/copy-to-ebx 0/imm32
74 $subx-braces-main:end:
75 e8/call syscall_exit/disp32
76
77 subx-braces:
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 55/push-ebp
115 89/<- %ebp 4/r32/esp
116
117 50/push-eax
118 51/push-ecx
119 52/push-edx
120 53/push-ebx
121 56/push-esi
122 57/push-edi
123
124 8b/-> *(ebp+8) 6/r32/esi
125
126 81 5/subop/subtract %esp 0x200/imm32
127 68/push 0x200/imm32/length
128 68/push 0/imm32/read
129 68/push 0/imm32/write
130 89/<- %ecx 4/r32/esp
131
132 81 5/subop/subtract %esp 0x80/imm32
133 68/push 0x80/imm32/length
134 68/push 0/imm32/top
135 89/<- %edx 4/r32/esp
136
137 c7 0/subop/copy %ebx 1/imm32
138
139 68/push 0/imm32/end
140 68/push 0/imm32/start
141 89/<- %edi 4/r32/esp
142 $subx-braces:line-loop:
143 (clear-stream %ecx)
144 (read-line-buffered %esi %ecx)
145 $subx-braces:check0:
146
147 81 7/subop/compare *ecx 0/imm32
148 0f 84/jump-if-= $subx-braces:break/disp32
149 (skip-chars-matching-whitespace %ecx)
150 $subx-braces:check-for-curly-open:
151
152
153 8b/-> *(ecx+4) 0/r32/eax
154 8a/copy-byte *(ecx+eax+0xc) 0/r32/AL
155 25/and-eax-with 0xff/imm32
156
157 3d/compare-eax-and 0x7b/imm32/open-curly
158 0f 85/jump-if-!= $subx-braces:check-for-curly-closed/disp32
159 $subx-braces:emit-curly-open:
160
161 (write-buffered *(ebp+0xc) "@loop")
162 (write-int32-hex-buffered *(ebp+0xc) %ebx)
163 (write-buffered *(ebp+0xc) ":")
164
165 (push %edx %ebx)
166
167 ff 0/subop/increment %ebx
168
169 e9/jump $subx-braces:next-line/disp32
170 $subx-braces:check-for-curly-closed:
171
172 3d/compare-eax-and 0x7d/imm32/close-curly
173 0f 85/jump-if-= $subx-braces:word-loop/disp32
174 $subx-braces:emit-curly-closed:
175
176 (pop %edx)
177
178 (write-buffered *(ebp+0xc) "@break")
179 (write-int32-hex-buffered *(ebp+0xc) %eax)
180 (write-buffered *(ebp+0xc) ":")
181
182 e9/jump $subx-braces:next-line/disp32
183 $subx-braces:word-loop:
184 (next-word-or-string %ecx %edi)
185 $subx-braces:check1:
186
187 (slice-empty? %edi)
188 3d/compare-eax-and 0/imm32/false
189 0f 85/jump-if-!= $subx-braces:next-line/disp32
190 $subx-braces:check-for-comment:
191
192
193 8b/-> *edi 0/r32/eax
194 8a/copy-byte *eax 0/r32/AL
195 25/and-eax-with 0xff/imm32
196
197 3d/compare-eax-and 0x23/imm32/hash
198 74/jump-if-= $subx-braces:word-loop/disp8
199 $subx-braces:check-for-break:
200
201
202 (slice-starts-with? %edi "break/")
203
204 3d/compare-eax-and 0/imm32/false
205 74/jump-if-= $subx-braces:check-for-loop/disp8
206 $subx-braces:emit-break:
207 (top %edx)
208
209 (write-buffered *(ebp+0xc) "@break")
210 (write-int32-hex-buffered *(ebp+0xc) %eax)
211
212 81 0/subop/add *edi 5/imm32/strlen
213
214 eb/jump $subx-braces:emit-word-slice/disp8
215 $subx-braces:check-for-loop:
216
217
218 (slice-starts-with? %edi "loop/")
219
220 3d/compare-eax-and 0/imm32/false
221 74/jump-if-= $subx-braces:emit-word-slice/disp8
222 $subx-braces:emit-loop:
223 (top %edx)
224
225 (write-buffered *(ebp+0xc) "@loop")
226 (write-int32-hex-buffered *(ebp+0xc) %eax)
227
228 81 0/subop/add *edi 4/imm32/strlen
229
230 $subx-braces:emit-word-slice:
231
232 (write-slice-buffered *(ebp+0xc) %edi)
233 (write-buffered *(ebp+0xc) Space)
234
235 e9/jump $subx-braces:word-loop/disp32
236 $subx-braces:next-line:
237
238 (write-buffered *(ebp+0xc) Newline)
239
240 e9/jump $subx-braces:line-loop/disp32
241 $subx-braces:break:
242 (flush *(ebp+0xc))
243 $subx-braces:end:
244
245 81 0/subop/add %esp 0x29c/imm32
246
247 5f/pop-to-edi
248 5e/pop-to-esi
249 5b/pop-to-ebx
250 5a/pop-to-edx
251 59/pop-to-ecx
252 58/pop-to-eax
253
254 89/<- %esp 5/r32/ebp
255 5d/pop-to-ebp
256 c3/return
257
258 test-subx-braces-passes-most-words-through:
259
260 55/push-ebp
261 89/<- %ebp 4/r32/esp
262
263 (clear-stream _test-input-stream)
264 (clear-stream _test-output-stream)
265 (clear-stream $_test-input-buffered-file->buffer)
266 (clear-stream $_test-output-buffered-file->buffer)
267
268 (write _test-input-stream "== abcd 0x1")
269 (subx-braces _test-input-buffered-file _test-output-buffered-file)
270
271 (flush _test-output-buffered-file)
272 +-- 5 lines: #? # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
277 (check-stream-equal _test-output-stream "== abcd 0x1 \n" "F - test-subx-braces-passes-most-words-through")
278
279 89/<- %esp 5/r32/ebp
280 5d/pop-to-ebp
281 c3/return
282
283 test-subx-braces-1:
284
285
286
287
288
289
290
291
292
293
294
295
296
297 55/push-ebp
298 89/<- %ebp 4/r32/esp
299
300 (clear-stream _test-input-stream)
301 (clear-stream _test-output-stream)
302 (clear-stream $_test-input-buffered-file->buffer)
303 (clear-stream $_test-output-buffered-file->buffer)
304
305 (write _test-input-stream "{\nab break/imm32\ncd loop/imm32\n}")
306 (subx-braces _test-input-buffered-file _test-output-buffered-file)
307
308 (flush _test-output-buffered-file)
309 +-- 5 lines: #? # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
314 (check-stream-equal _test-output-stream "@loop0x00000001:\nab @break0x00000001/imm32 \ncd @loop0x00000001/imm32 \n@break0x00000001:\n" "F - test-subx-braces-1")
315
316 89/<- %esp 5/r32/ebp
317 5d/pop-to-ebp
318 c3/return
319
320 test-subx-braces-2:
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338 55/push-ebp
339 89/<- %ebp 4/r32/esp
340
341 (clear-stream _test-input-stream)
342 (clear-stream _test-output-stream)
343 (clear-stream $_test-input-buffered-file->buffer)
344 (clear-stream $_test-output-buffered-file->buffer)
345
346 (write _test-input-stream "{\n{\nab break/imm32\n}\ncd loop/imm32\n}")
347 (subx-braces _test-input-buffered-file _test-output-buffered-file)
348
349 (flush _test-output-buffered-file)
350 +-- 5 lines: #? # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
355 (check-stream-equal _test-output-stream "@loop0x00000001:\n@loop0x00000002:\nab @break0x00000002/imm32 \n@break0x00000002:\ncd @loop0x00000001/imm32 \n@break0x00000001:\n" "F - test-subx-braces-2")
356
357 89/<- %esp 5/r32/ebp
358 5d/pop-to-ebp
359 c3/return