https://github.com/akkartik/mu/blob/master/apps/crenshaw2-1.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 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . .
36
37
38
39
40 68/push Heap/imm32
41 68/push Heap-size/imm32
42
43 e8/call new-segment/disp32
44
45 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
46
47
48
49 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 0/disp8 1/imm32
50 7e/jump-if-lesser-or-equal $run-main/disp8
51
52
53
54 68/push "test"/imm32
55 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 .
56
57 e8/call kernel-string-equal?/disp32
58
59 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
60
61 3d/compare-eax-and 0/imm32
62 74/jump-if-equal $run-main/disp8
63
64 e8/call run-tests/disp32
65
66 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/ebx Num-test-failures/disp32
67 eb/jump $main:end/disp8
68 $run-main:
69
70
71 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32
72 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . .
73
74
75 c7 0/subop/copy 0/mod/direct 0/rm32/eax . . . . . 0/imm32
76
77
78 50/push-eax/ed
79 68/push 2/imm32/stderr
80 68/push 1/imm32/stdout
81 68/push Stdin/imm32
82
83 e8/call compile/disp32
84
85 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32
86
87 bb/copy-to-ebx 0/imm32
88 $main:end:
89 b8/copy-to-eax 1/imm32/exit
90 cd/syscall 0x80/imm8
91
92
93 compile:
94
95 55/push-ebp
96 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . .
97
98 50/push-eax
99 51/push-ecx
100
101
102
103 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 .
104
105 e8/call get-char/disp32
106
107 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
108
109
110
111
112
113 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x13/imm32
114 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . .
115
116
117 c7 0/subop/copy 1/mod/*+disp8 1/rm32/ecx . . . . 8/disp8 7/imm32
118
119
120 51/push-ecx
121
122 e8/call clear-stream/disp32
123
124 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
125
126
127
128 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x14/disp8 .
129 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 .
130 51/push-ecx/num
131 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 .
132
133 e8/call get-num/disp32
134
135 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32
136
137
138
139
140
141
142
143 68/push "bb/copy-to-ebx "/imm32
144 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 .
145
146 e8/call write/disp32
147
148 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
149
150
151 51/push-ecx/num
152 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 .
153
154 e8/call write-stream/disp32
155
156 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
157
158
159 68/push Newline/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 "b8/copy-to-eax 1/imm32/exit\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
174
175 68/push "cd/syscall 0x80/imm8\n"/imm32
176 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 .
177
178 e8/call write/disp32
179
180 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
181 $compile:end:
182
183 59/pop-to-ecx
184 58/pop-to-eax
185
186 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . .
187 5d/pop-to-ebp
188 c3/return
189
190
191
192
193 get-num:
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214 55/push-ebp
215 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . .
216
217
218
219 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Look/disp32 .
220
221 e8/call is-digit?/disp32
222
223 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
224
225 3d/compare-eax-and 0/imm32
226 75/jump-if-not-equal $get-num:main/disp8
227
228
229 68/push "integer"/imm32
230 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 .
231 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x14/disp8 .
232
233 e8/call expected/disp32
234
235 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32
236 $get-num:main:
237
238
239 50/push-eax
240 51/push-ecx
241 52/push-edx
242 53/push-ebx
243 56/push-esi
244 57/push-edi
245
246
247 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 .
248
249 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 .
250
251 8b/copy 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . .
252
253 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 8/disp8 .
254
255 39/compare 3/mod/direct 2/rm32/edx . . . 1/r32/ecx . .
256 7d/jump-if-lesser $get-num:stage2/disp8
257
258
259 68/push "get-num: too many digits in number"/imm32
260 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 .
261 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x14/disp8 .
262
263 e8/call error/disp32
264
265 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32
266 $get-num:stage2:
267
268 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/edi 1/index/ecx . 3/r32/ebx 0xc/disp8 .
269 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/eax Look/disp32 .
270 88/copy-byte 0/mod/indirect 3/rm32/ebx . . . 0/r32/AL . .
271
272 41/increment-ecx
273
274
275 56/push-esi
276
277 e8/call get-char/disp32
278
279 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
280 $get-num:loop-end:
281
282 89/copy 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . .
283 $get-num:end:
284
285 5f/pop-to-edi
286 5e/pop-to-esi
287 5b/pop-to-ebx
288 5a/pop-to-edx
289 59/pop-to-ecx
290 58/pop-to-eax
291
292 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . .
293 5d/pop-to-ebp
294 c3/return
295
296 test-get-num-reads-single-digit:
297
298
299 55/push-ebp
300 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . .
301
302
303
304 68/push _test-stream/imm32
305
306 e8/call clear-stream/disp32
307
308 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
309
310
311 b8/copy-to-eax _test-buffered-file/imm32
312 05/add-to-eax 4/imm32
313 50/push-eax
314
315 e8/call clear-stream/disp32
316
317 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
318
319
320 68/push _test-output-stream/imm32
321
322 e8/call clear-stream/disp32
323
324 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
325
326
327 68/push _test-error-stream/imm32
328
329 e8/call clear-stream/disp32
330
331 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
332
333
334
335 68/push "3"/imm32
336 68/push _test-stream/imm32
337
338 e8/call write/disp32
339
340 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
341
342
343 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32
344 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . .
345
346
347 68/push 0x10/imm32/nbytes-of-args-for-get-num
348 50/push-eax/ed
349
350 e8/call tailor-exit-descriptor/disp32
351
352 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
353
354
355
356 68/push _test-buffered-file/imm32
357
358 e8/call get-char/disp32
359
360 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
361
362
363 50/push-eax/ed
364 68/push _test-error-stream/imm32
365 68/push _test-output-stream/imm32
366 68/push _test-buffered-file/imm32
367
368 e8/call get-num/disp32
369
370
371 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32
372
373
374 68/push "F - test-get-num-reads-single-digit"/imm32
375 68/push 0x33/imm32
376 b8/copy-to-eax _test-output-stream/imm32
377 ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 0xc/disp8 .
378
379 e8/call check-ints-equal/disp32
380
381 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32
382
383 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
384 5d/pop-to-ebp
385 c3/return
386
387 test-get-num-aborts-on-non-digit-in-Look:
388
389
390 55/push-ebp
391 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . .
392
393
394
395 68/push _test-stream/imm32
396
397 e8/call clear-stream/disp32
398
399 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
400
401
402 b8/copy-to-eax _test-buffered-file/imm32
403 05/add-to-eax 4/imm32
404 50/push-eax
405
406 e8/call clear-stream/disp32
407
408 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
409
410
411 68/push _test-output-stream/imm32
412
413 e8/call clear-stream/disp32
414
415 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
416
417
418 68/push _test-error-stream/imm32
419
420 e8/call clear-stream/disp32
421
422 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
423
424
425
426 68/push "3"/imm32
427 68/push _test-stream/imm32
428
429 e8/call write/disp32
430
431 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
432
433
434 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32
435 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . .
436
437
438 68/push 0x10/imm32/nbytes-of-args-for-get-num
439 50/push-eax/ed
440
441 e8/call tailor-exit-descriptor/disp32
442
443 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
444
445
446
447 50/push-eax/ed
448 68/push _test-error-stream/imm32
449 68/push _test-output-stream/imm32
450 68/push _test-buffered-file/imm32
451
452 e8/call get-num/disp32
453
454
455 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32
456
457
458
459 68/push "F - test-get-num-aborts-on-non-digit-in-Look"/imm32
460 68/push 2/imm32
461
462 ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 .
463
464 e8/call check-ints-equal/disp32
465
466 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32
467
468 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
469 5d/pop-to-ebp
470 c3/return
471
472
473
474
475 expected:
476
477 55/push-ebp
478 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . .
479
480
481 68/push "Error: "/imm32
482 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 .
483
484 e8/call write/disp32
485
486 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
487
488
489 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 .
490 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 .
491
492 e8/call write/disp32
493
494 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
495
496
497 68/push " expected\n"/imm32
498 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 .
499
500 e8/call write/disp32
501
502 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32
503
504
505 68/push 1/imm32
506 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 .
507
508 e8/call stop/disp32
509
510 $expected:dead-end:
511
512 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . .
513 5d/pop-to-ebp
514 c3/return
515
516
517 get-char:
518
519 55/push-ebp
520 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . .
521
522 50/push-eax
523
524
525 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 .
526
527 e8/call read-byte-buffered/disp32
528
529 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32
530
531 89/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/eax Look/disp32 .
532 $get-char:end:
533
534 58/pop-to-eax
535
536 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . .
537 5d/pop-to-ebp
538 c3/return
539
540 is-digit?:
541
542 55/push-ebp
543 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . .
544
545 b8/copy-to-eax 0/imm32
546
547 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 0x30/imm32
548 7c/jump-if-lesser $is-digit?:end/disp8
549
550 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 0x39/imm32
551 7f/jump-if-greater $is-digit?:end/disp8
552
553 b8/copy-to-eax 1/imm32
554 $is-digit?:end:
555
556 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . .
557 5d/pop-to-ebp
558 c3/return
559
560 == data
561
562 Look:
563 0/imm32
564
565