https://github.com/akkartik/mu/blob/master/068error-byte.subx
 1 # Print an error message followed by the text representation of a byte. Then exit.
 2 
 3 == code
 4 #   instruction                     effective address                                                   register    displacement    immediate
 5 # . op          subop               mod             rm32          base        index         scale       r32
 6 # . 1-3 bytes   3 bits              2 bits          3 bits        3 bits      3 bits        2 bits      2 bits      0/1/2/4 bytes   0/1/2/4 bytes
 7 
 8 #? Entry:  # manual test
 9 #?     # . var ed/eax : (ref exit-descriptor)
10 #?     81          5/subop/subtract    3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # subtract from esp
11 #?     89/copy                         3/mod/direct    0/rm32/eax    .           .             .           4/r32/esp   .               .                 # copy esp to eax
12 #?     # . configure ed to really exit()
13 #?     # . . ed->target = 0
14 #?     c7          0/subop/copy        0/mod/direct    0/rm32/eax    .           .             .           .           .               0/imm32           # copy to *eax
15 #?     # . error-byte(ed, Stdout, msg, 34)
16 #?     68/push  0x34/imm32
17 #?     68/push  "abc"/imm32
18 #?     68/push  Stderr/imm32
19 #?     50/push-eax
20 #?     e8/call  error-byte/disp32
21 #?     # . syscall(exit, Num-test-failures)
22 #?     8b/copy                         0/mod/indirect  5/rm32/.disp32            .             .           3/r32/ebx   Num-test-failures/disp32          # copy *Num-test-failures to ebx
23 #?     b8/copy-to-eax  1/imm32/exit
24 #?     cd/syscall  0x80/imm8
25 
26 # write(out, "Error: "+msg+": "+byte) then stop(ed, 1)
27 error-byte:  # ed : (addr exit-descriptor), out : (addr buffered-file), msg : (addr array byte), n : byte
28     # . prologue
29     55/push-ebp
30     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
31     # write-buffered(out, "Error: ")
32     # . . push args
33     68/push  "Error: "/imm32
34     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0xc/disp8       .                 # push *(ebp+12)
35     # . . call
36     e8/call  write-buffered/disp32
37     # . . discard args
38     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
39     # write-buffered(out, msg)
40     # . . push args
41     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0x10/disp8      .                 # push *(ebp+16)
42     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0xc/disp8       .                 # push *(ebp+12)
43     # . . call
44     e8/call  write-buffered/disp32
45     # . . discard args
46     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
47     # write-buffered(out, ": ")
48     # . . push args
49     68/push  ": "/imm32
50     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0xc/disp8       .                 # push *(ebp+12)
51     # . . call
52     e8/call  write-buffered/disp32
53     # . . discard args
54     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
55     # print-byte-buffered(out, byte)
56     # . . push args
57     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0x14/disp8      .                 # push *(ebp+20)
58     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0xc/disp8       .                 # push *(ebp+12)
59     # . . call
60     e8/call  print-byte-buffered/disp32
61     # . . discard args
62     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
63     # write-buffered(out, Newline)
64     # . . push args
65     68/push  Newline/imm32
66     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0xc/disp8       .                 # push *(ebp+12)
67     # . . call
68     e8/call  write-buffered/disp32
69     # . . discard args
70     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
71     # flush(out)
72     # . . push args
73     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0xc/disp8       .                 # push *(ebp+12)
74     # . . call
75     e8/call  flush/disp32
76     # . . discard args
77     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
78     # stop(ed, 1)
79     # . . push args
80     68/push  1/imm32
81     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
82     # . . call
83     e8/call  stop/disp32
84     # should never get past this point
85 $error-byte:dead-end:
86     # . epilogue
87     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
88     5d/pop-to-ebp
89     c3/return
90 
91 # . . vim:nowrap:textwidth=0