https://github.com/akkartik/mu/blob/master/apps/factorial4.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 0x10000 Heap)
24 
25     # - if argc > 1, then return run_tests()
26     {
27       # if (argc <= 1) break
28       81 7/subop/compare *ebp 1/imm32
29       7e/jump-if-lesser-or-equal break/disp8
30       # if (!kernel-string-equal?(argv[1], "test")) break
31       (kernel-string-equal? *(ebp+8) "test")  # => eax
32       3d/compare-eax-and 0/imm32
33       74/jump-if-equal break/disp8
34       #
35       (run-tests)
36       # eax = *Num-test-failures
37       8b/-> *Num-test-failures 3/r32/ebx
38     }
39     # if (argc <= 1) factorial(5)
40     {
41       # if (argc > 1) break
42       81 7/subop/compare *ebp 1/imm32
43       7f/jump-if-greater break/disp8
44       # eax = factorial(5)
45       (factorial 5)
46       # syscall(exit, eax)
47       89/<- %ebx 0/r32/eax
48     }
49 
50     b8/copy-to-eax 1/imm32/exit
51     cd/syscall 0x80/imm8
52 
53 factorial:  # n : int -> int/eax
54     # . prologue
55     55/push-ebp
56     89/<- %ebp 4/r32/esp
57     # save registers
58     53/push-ebx
59     # if (n <= 1) return 1
60     81 7/subop/compare *(ebp+8) 1/imm32
61     {
62       7f/jump-if-greater break/disp8
63       b8/copy-to-eax 1/imm32
64     }
65     # if (n > 1) return n * factorial(n-1)
66     {
67       7e/jump-if-lesser-or-equal break/disp8
68       8b/-> *(ebp+8) 3/r32/ebx
69       4b/decrement-ebx
70       (factorial %ebx)  # => eax
71       f7 4/subop/multiply-into-eax *(ebp+8)
72     }
73     # restore registers
74     5b/pop-to-ebx
75     # . epilogue
76     89/<- %esp 5/r32/ebp
77     5d/pop-to-ebp
78     c3/return
79 
80 test-factorial:
81     (factorial 5)
82     (check-ints-equal %eax 0x78 "F - test-factorial")
83     c3/return