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
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 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 00 00 00 00
580
581 _test-output-stream:
582
583 00 00 00 00
584
585 00 00 00 00
586
587 08 00 00 00
588
589 00 00 00 00 00 00 00 00
590
591 _test-error-stream:
592
593 00 00 00 00
594
595 00 00 00 00
596
597 08 00 00 00
598
599 00 00 00 00 00 00 00 00
600
601