https://github.com/akkartik/mu/blob/main/linux/ex7.subx
 1 # Example showing file syscalls.
 2 #
 3 # Create a file, open it for writing, write a character to it, close it, open
 4 # it for reading, read a character from it, close it, delete it, and return
 5 # the character read.
 6 #
 7 # To run:
 8 #   $ bootstrap/bootstrap translate ex7.subx -o ex7
 9 #   $ bootstrap/bootstrap run ex7
10 # Expected result:
11 #   $ echo $?
12 #   97
13 
14 == code
15 #   instruction                     effective address                                                   register    displacement    immediate
16 # . op          subop               mod             rm32          base        index         scale       r32
17 # . 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
18 
19 Entry:
20     # creat(Filename)
21     bb/copy-to-ebx  Filename/imm32
22     b9/copy-to-ecx  0x180/imm32/fixed-perms
23     e8/call  syscall_creat/disp32
24 
25     # stream = open(Filename, O_WRONLY, 0)  # we can't use 'fd' because it looks like a hex byte
26     bb/copy-to-ebx  Filename/imm32
27     b9/copy-to-ecx  1/imm32/wronly
28     ba/copy-to-edx  0x180/imm32/fixed-perms
29     e8/call  syscall_open/disp32
30     # save stream
31     bb/copy-to-ebx  Stream/imm32
32     89/copy                         0/mod/indirect  3/rm32/ebx    .           .             .           0/r32/eax   .               .                 # copy eax to *ebx
33 
34     # write(Stream, "a", 1)
35     # . load stream
36     bb/copy-to-ebx  Stream/imm32
37     8b/copy                         0/mod/indirect  3/rm32/ebx    .           .             .           3/r32/ebx   .               .                 # copy *ebx to ebx
38     # .
39     b9/copy-to-ecx  A/imm32
40     ba/copy-to-edx  1/imm32/size
41     e8/call  syscall_write/disp32
42 
43     # close(Stream)
44     # . load stream
45     bb/copy-to-ebx  Stream/imm32
46     8b/copy                         0/mod/indirect  3/rm32/ebx    .           .             .           3/r32/ebx   .               .                 # copy *ebx to ebx
47     # .
48     e8/call  syscall_close/disp32
49 
50     # stream = open(Filename, O_RDONLY, 0)
51     bb/copy-to-ebx  Filename/imm32
52     b9/copy-to-ecx  0/imm32/rdonly
53     ba/copy-to-edx  0x180/imm32/fixed-perms
54     e8/call  syscall_open/disp32
55     # . save Stream
56     bb/copy-to-ebx  Stream/imm32
57     89/copy                         0/mod/indirect  3/rm32/ebx    .           .             .           0/r32/eax   .               .                 # copy eax to *ebx
58 
59     # read(Stream, B, 1)
60     # . load stream
61     bb/copy-to-ebx  Stream/imm32
62     8b/copy                         0/mod/indirect  3/rm32/ebx    .           .             .           3/r32/ebx   .               .                 # copy *ebx to ebx
63     # .
64     b9/copy-to-ecx  B/imm32
65     ba/copy-to-edx  1/imm32/size
66     e8/call  syscall_read/disp32
67 
68     # close(Stream)
69     # . load stream
70     bb/copy-to-ebx  Stream/imm32
71     8b/copy                         0/mod/indirect  3/rm32/ebx    .           .             .           3/r32/ebx   .               .                 # copy *ebx to ebx
72     #
73     e8/call  syscall_close/disp32
74 
75     # unlink(filename)
76     bb/copy-to-ebx  Filename/imm32
77     e8/call  syscall_unlink/disp32
78 
79     # exit(b)
80     # . load b
81     bb/copy-to-ebx  B/imm32
82     8b/copy                         0/mod/indirect  3/rm32/ebx    .           .             .           3/r32/ebx   .               .                 # copy *ebx to ebx
83     #
84     e8/call  syscall_exit/disp32
85 
86 == data
87 
88 Stream:
89     0/imm32
90 A:
91     61/imm32/A
92 B:
93     0/imm32
94 Filename:
95     2e 66 6f 6f 00 00 00 00
96 #   .  f  o  o  null
97 
98 # . . vim:nowrap:textwidth=0