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