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 _test-output-stream:
563
564 0/imm32
565
566 0/imm32
567
568 8/imm32
569
570 00 00 00 00 00 00 00 00
571
572 _test-error-stream:
573
574 0/imm32
575
576 0/imm32
577
578 0x40/imm32
579
580 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
581 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
582 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
583 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
584
585