https://github.com/akkartik/mu/blob/master/105files.subx
 1 == code
 2 
 3 open:  # filename: (addr array byte), write?: boolean, out: (addr handle buffered-file)
 4     # hard-coded parameter: file-buffer-size of created buffered-file
 5     # . prologue
 6     55/push-ebp
 7     89/<- %ebp 4/r32/esp
 8     # . save registers
 9     50/push-eax
10     51/push-ecx
11     52/push-edx
12     53/push-ebx
13     56/push-esi
14     57/push-edi
15     # ecx = filename
16     8b/-> *(ebp+8) 1/r32/ecx
17     # var size/edx: int = filename->length + 1 for the trailing null character
18     8b/-> *ecx 2/r32/edx
19     42/increment-edx
20     # var s/esi: (stream size)
21     29/subtract-from %esp 2/r32/edx
22     52/push-edx  # size
23     68/push 0/imm32/read
24     68/push 0/imm32/write
25     89/<- %esi 4/r32/esp
26     # copy filename and a final null character
27     (clear-stream %esi)
28     (write %esi %ecx)
29     # spill edx
30     52/push-edx
31     # var fd/ecx: fd = open(filename)
32     8d/copy-address *(esi+0xc) 3/r32/ebx
33     8b/-> *(ebp+0xc) 1/r32/ecx/flags
34     ba/copy-to-edx 0x180/imm32/permissions
35     e8/call syscall_open/disp32
36     89/<- %ecx 0/r32/eax
37     # restore edx
38     5a/pop-to-edx
39     # allocate a buffered-file
40     (allocate Heap 0x1010 *(ebp+0x10))  # file-buffer-size + 16 for other fields
41     # var out-addr/edi: (addr buffered-file)
42     8b/-> *(ebp+0x10) 7/r32/edi
43     (lookup *edi *(edi+4))  # => eax
44     89/<- %edi 0/r32/eax
45     # out-addr->size = 4KB
46     c7 0/subop/copy *(edi+0xc) 0x1000/imm32/file-buffer-size  # Stream-size + 4 for fd
47     # out-addr->fd = fd
48     89/<- *edi 1/r32/ecx
49 $open:end:
50     # . reclaim locals
51     01/add-to %esp 2/r32/edx
52     81 0/subop/add %esp 0xc/imm32
53     # . restore registers
54     5f/pop-to-edi
55     5e/pop-to-esi
56     5b/pop-to-ebx
57     5a/pop-to-edx
58     59/pop-to-ecx
59     58/pop-to-eax
60     # . epilogue
61     89/<- %esp 5/r32/ebp
62     5d/pop-to-ebp
63     c3/return