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
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 get-num:
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211 55/push-EBP
212 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
213
214
215
216 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Look/disp32 .
217
218 e8/call is-digit?/disp32
219
220 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
221
222 3d/compare-EAX-and 0/imm32
223 75/jump-if-not-equal $get-num:main/disp8
224
225
226 68/push "integer"/imm32
227 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0x10/disp8 .
228 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0x14/disp8 .
229
230 e8/call expected/disp32
231
232 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32
233 $get-num:main:
234
235
236 50/push-EAX
237 51/push-ECX
238 52/push-EDX
239 53/push-EBX
240 56/push-ESI
241 57/push-EDI
242
243
244 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 8/disp8 .
245
246 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 7/r32/EDI 0xc/disp8 .
247
248 8b/copy 0/mod/indirect 7/rm32/EDI . . . 1/r32/ECX . .
249
250 8b/copy 1/mod/*+disp8 7/rm32/EDI . . . 2/r32/EDX 8/disp8 .
251
252 39/compare 3/mod/direct 2/rm32/EDX . . . 1/r32/ECX . .
253 7d/jump-if-lesser $get-num:stage2/disp8
254
255
256 68/push "get-num: too many digits in number"/imm32
257 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0x10/disp8 .
258 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0x14/disp8 .
259
260 e8/call error/disp32
261
262 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32
263 $get-num:stage2:
264
265 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/EDI 1/index/ECX . 3/r32/EBX 0xc/disp8 .
266 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/EAX Look/disp32 .
267 88/copy-byte 0/mod/indirect 3/rm32/EBX . . . 0/r32/AL . .
268
269 41/increment-ECX
270
271
272 56/push-ESI
273
274 e8/call get-char/disp32
275
276 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
277 $get-num:loop-end:
278
279 89/copy 0/mod/indirect 7/rm32/EDI . . . 1/r32/ECX . .
280 $get-num:end:
281
282 5f/pop-to-EDI
283 5e/pop-to-ESI
284 5b/pop-to-EBX
285 5a/pop-to-EDX
286 59/pop-to-ECX
287 58/pop-to-EAX
288
289 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . .
290 5d/pop-to-EBP
291 c3/return
292
293 test-get-num-reads-single-digit:
294
295
296 55/push-EBP
297 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
298
299
300
301 68/push _test-stream/imm32
302
303 e8/call clear-stream/disp32
304
305 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
306
307
308 b8/copy-to-EAX _test-buffered-file/imm32
309 05/add-to-EAX 4/imm32
310 50/push-EAX
311
312 e8/call clear-stream/disp32
313
314 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
315
316
317 68/push _test-output-stream/imm32
318
319 e8/call clear-stream/disp32
320
321 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
322
323
324 68/push _test-error-stream/imm32
325
326 e8/call clear-stream/disp32
327
328 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
329
330
331
332 68/push "3"/imm32
333 68/push _test-stream/imm32
334
335 e8/call write/disp32
336
337 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
338
339
340 81 5/subop/subtract 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
341 89/copy 3/mod/direct 0/rm32/EAX . . . 4/r32/ESP . .
342
343
344 68/push 0x10/imm32/nbytes-of-args-for-get-num
345 50/push-EAX/ed
346
347 e8/call tailor-exit-descriptor/disp32
348
349 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
350
351
352
353 68/push _test-buffered-file/imm32
354
355 e8/call get-char/disp32
356
357 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
358
359
360 50/push-EAX/ed
361 68/push _test-error-stream/imm32
362 68/push _test-output-stream/imm32
363 68/push _test-buffered-file/imm32
364
365 e8/call get-num/disp32
366
367
368 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32
369
370
371 68/push "F - test-get-num-reads-single-digit"/imm32
372 68/push 0x33/imm32
373 b8/copy-to-EAX _test-output-stream/imm32
374 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 .
375
376 e8/call check-ints-equal/disp32
377
378 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32
379
380 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
381 5d/pop-to-EBP
382 c3/return
383
384 test-get-num-aborts-on-non-digit-in-Look:
385
386
387 55/push-EBP
388 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
389
390
391
392 68/push _test-stream/imm32
393
394 e8/call clear-stream/disp32
395
396 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
397
398
399 b8/copy-to-EAX _test-buffered-file/imm32
400 05/add-to-EAX 4/imm32
401 50/push-EAX
402
403 e8/call clear-stream/disp32
404
405 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
406
407
408 68/push _test-output-stream/imm32
409
410 e8/call clear-stream/disp32
411
412 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
413
414
415 68/push _test-error-stream/imm32
416
417 e8/call clear-stream/disp32
418
419 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
420
421
422
423 68/push "3"/imm32
424 68/push _test-stream/imm32
425
426 e8/call write/disp32
427
428 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
429
430
431 81 5/subop/subtract 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
432 89/copy 3/mod/direct 0/rm32/EAX . . . 4/r32/ESP . .
433
434
435 68/push 0x10/imm32/nbytes-of-args-for-get-num
436 50/push-EAX/ed
437
438 e8/call tailor-exit-descriptor/disp32
439
440 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
441
442
443
444 50/push-EAX/ed
445 68/push _test-error-stream/imm32
446 68/push _test-output-stream/imm32
447 68/push _test-buffered-file/imm32
448
449 e8/call get-num/disp32
450
451
452 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32
453
454
455
456 68/push "F - test-get-num-aborts-on-non-digit-in-Look"/imm32
457 68/push 2/imm32
458
459 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 .
460
461 e8/call check-ints-equal/disp32
462
463 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32
464
465 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
466 5d/pop-to-EBP
467 c3/return
468
469
470
471
472 expected:
473
474 55/push-EBP
475 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
476
477
478 68/push "Error: "/imm32
479 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 .
480
481 e8/call write/disp32
482
483 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
484
485
486 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0x10/disp8 .
487 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 .
488
489 e8/call write/disp32
490
491 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
492
493
494 68/push " expected\n"/imm32
495 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 .
496
497 e8/call write/disp32
498
499 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32
500
501
502 68/push 1/imm32
503 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 .
504
505 e8/call stop/disp32
506
507 $expected:dead-end:
508
509 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . .
510 5d/pop-to-EBP
511 c3/return
512
513
514 get-char:
515
516 55/push-EBP
517 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
518
519 50/push-EAX
520
521
522 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 .
523
524 e8/call read-byte-buffered/disp32
525
526 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32
527
528 89/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/EAX Look/disp32 .
529 $get-char:end:
530
531 58/pop-to-EAX
532
533 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . .
534 5d/pop-to-EBP
535 c3/return
536
537 is-digit?:
538
539 55/push-EBP
540 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . .
541
542 b8/copy-to-EAX 0/imm32
543
544 81 7/subop/compare 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 0x30/imm32
545 7c/jump-if-lesser $is-digit?:end/disp8
546
547 81 7/subop/compare 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 0x39/imm32
548 7f/jump-if-greater $is-digit?:end/disp8
549
550 b8/copy-to-EAX 1/imm32
551 $is-digit?:end:
552
553 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . .
554 5d/pop-to-EBP
555 c3/return
556
557 == data
558
559 Look:
560 0/imm32
561
562