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