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