https://github.com/akkartik/mu/blob/master/subx/061error.subx
 1 # Print an error message and 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 # main:
 9     e8/call  run-tests/disp32  # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'.
10     # syscall(exit, Num-test-failures)
11     8b/copy                         0/mod/indirect  5/rm32/.disp32            .             .           3/r32/EBX   Num-test-failures/disp32          # copy *Num-test-failures to EBX
12     b8/copy-to-EAX  1/imm32/exit
13     cd/syscall  0x80/imm8
14 
15 # write(out, "Error: "+msg+"\n") then stop(ed, 1)
16 error:  # ed : (address exit-descriptor), out : fd or (address stream), msg : (address array byte) -> <void>
17     # . prolog
18     55/push-EBP
19     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
20     # write(out, "Error: ")
21     # . . push args
22     68/push  "Error: "/imm32
23     ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           0xc/disp8       .                 # push *(EBP+12)
24     # . . call
25     e8/call  write/disp32
26     # . . discard args
27     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
28     # write(out, msg)
29     # . . push args
30     ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           0x10/disp8      .                 # push *(EBP+16)
31     ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           0xc/disp8       .                 # push *(EBP+12)
32     # . . call
33     e8/call  write/disp32
34     # . . discard args
35     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
36     # write(out, Newline)
37     # . . push args
38     68/push  Newline/imm32
39     ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           0xc/disp8       .                 # push *(EBP+12)
40     # . . call
41     e8/call  write/disp32
42     # . . discard args
43     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
44     # stop(ed, 1)
45     # . . push args
46     68/push  1/imm32
47     ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           8/disp8         .                 # push *(EBP+8)
48     # . . call
49     e8/call  stop/disp32
50     # should never get past this point
51 $error:dead-end:
52     # . epilog
53     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
54     5d/pop-to-EBP
55     c3/return
56 
57 # . . vim:nowrap:textwidth=0