https://github.com/akkartik/mu/blob/master/apps/factorial3.subx
 1 ## compute the factorial of 5, and return the result in the exit code
 2 #
 3 # To run:
 4 #   $ ./ntranslate init.linux 0*.subx apps/factorial.subx -o apps/factorial
 5 #   $ ./subx run apps/factorial
 6 # Expected result:
 7 #   $ echo $?
 8 #   120
 9 #
10 # You can also run the automated test suite:
11 #   $ ./subx run apps/factorial test
12 # Expected output:
13 #   ........
14 # Every '.' indicates a passing test. Failing tests get a 'F'.
15 
16 == code
17 
18 Entry:  # run tests if necessary, compute `factorial(5)` if not
19     # . prologue
20     89/<- %ebp 4/r32/esp
21 
22     # initialize heap
23     (new-segment Heap-size Heap)
24 
25     # - if argc > 1 and argv[1] == "test", then return run_tests()
26     # if (argc <= 1) goto run-main
27     81 7/subop/compare *ebp 1/imm32
28     7e/jump-if-lesser-or-equal $run-main/disp8
29     # if (!kernel-string-equal?(argv[1], "test")) goto run-main
30     (kernel-string-equal? *(ebp+8) "test")  # => eax
31     # . if (eax == 0) goto run-main
32     3d/compare-eax-and 0/imm32
33     74/jump-if-equal $run-main/disp8
34     #
35     (run-tests)
36     # syscall(exit, *Num-test-failures)
37     8b/-> *Num-test-failures 3/r32/ebx
38     eb/jump $main:end/disp8
39 $run-main:
40     # - otherwise
41     (factorial 5)  # => eax
42     # syscall(exit, eax)
43     89/<- %ebx 0/r32/eax
44 $main:end:
45     b8/copy-to-eax 1/imm32/exit
46     cd/syscall 0x80/imm8
47 
48 factorial:  # n : int -> int/eax
49     # . prologue
50     55/push-ebp
51     89/<- %ebp 4/r32/esp
52     # save registers
53     53/push-ebx
54     # if (n <= 1) return 1
55     b8/copy-to-eax 1/imm32
56     81 7/subop/compare *(ebp+8) 1/imm32
57     7e/jump-if-<= $factorial:end/disp8
58     # ebx = n-1
59     8b/-> *(ebp+8) 3/r32/ebx
60     4b/decrement-ebx
61     #
62     (factorial %ebx)  # => eax
63     # return n * factorial(n-1)
64     f7 4/subop/multiply-into-eax *(ebp+8)
65     # TODO: check for overflow
66 $factorial:end:
67     # restore registers
68     5b/pop-to-ebx
69     # . epilogue
70     89/<- %esp 5/r32/ebp
71     5d/pop-to-ebp
72     c3/return
73 
74 test-factorial:
75     (factorial 5)
76     (check-ints-equal %eax 0x78 "F - test-factorial")
77     c3/return