https://github.com/akkartik/mu/blob/main/mu-init.subx
 1 # Initialize the minimal runtime for Mu programs.
 2 #
 3 # See translate_mu for how this file is used.
 4 #
 5 # Mu programs start at a function called 'main' with this signature:
 6 #   fn main args: (addr array addr array byte) -> _/ebx: int
 7 # If your program doesn't need commandline arguments you can drop it:
 8 #   fn main -> _/ebx: int
 9 #
10 # Notice that the output must be in ebx, so that the exit() syscall can pick
11 # it up.
12 
13 == code
14 
15 Entry:
16     # we don't use ebp in Entry; just initialize it
17     bd/copy-to-ebp 0/imm32
18     # - save argc and argv
19     # var argc-and-argv/esi
20     89/<- %esi 4/r32/esp
21 $Entry:initialize-heap:
22     # - initialize the heap
23     (new-segment *Heap-size Heap)
24 $Entry:initialize-args:
25     # - convert argv from null-terminated 'kernel' strings to length-prefixed Mu strings
26     # var argc/edx: int
27     8b/-> *esi 2/r32/edx
28     # argc is in words; convert it to bytes
29     c1/shift 4/subop/left %edx 2/imm8
30     # var tmp/ebx: handle
31     68/push 0/imm32
32     68/push 0/imm32
33     89/<- %ebx 4/r32/esp
34     # var args/edi: (addr array (addr array byte))
35     (allocate-array Heap %edx %ebx)
36     (lookup *ebx *(ebx+4))  # => eax
37     89/<- %edi 0/r32/eax
38     # var curr/ecx: (addr kernel-string) = argv
39     8d/copy-address *(esi+4) 1/r32/ecx
40     # var max/edx: (addr kernel-string) = argv+4+argc
41     8d/copy-address *(ecx+edx) 2/r32/edx
42     # var dest/esi: (addr (addr array byte)) = args+4
43     8d/copy-address *(edi+4) 6/r32/esi
44     {
45       # if (curr >= max) break
46       39/compare %ecx 2/r32/edx
47       73/jump-if-addr>= break/disp8
48       # *dest = kernel-string-to-string(*curr)
49       (kernel-string-to-string Heap *ecx %ebx)
50       (lookup *ebx *(ebx+4))  # => eax
51       89/<- *esi 0/r32/eax
52       # curr += 4
53       81 0/subop/add %ecx 4/imm32
54       # dest += 4
55       81 0/subop/add %esi 4/imm32
56       #
57       eb/jump loop/disp8
58     }
59     # - run Mu program
60     (main %edi)  # => ebx
61     # - exit
62     (syscall_exit)