From 3350c34a74844e21ea69077e01efff3bae64bdcd Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Tue, 23 Mar 2021 17:31:08 -0700 Subject: . --- html/linux/factorial4.subx.html | 150 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 html/linux/factorial4.subx.html (limited to 'html/linux/factorial4.subx.html') diff --git a/html/linux/factorial4.subx.html b/html/linux/factorial4.subx.html new file mode 100644 index 00000000..57fa57a0 --- /dev/null +++ b/html/linux/factorial4.subx.html @@ -0,0 +1,150 @@ + + + + +Mu - linux/factorial4.subx + + + + + + + + + + +https://github.com/akkartik/mu/blob/main/linux/factorial4.subx +
+ 1 ## compute the factorial of 5, and return the result in the exit code
+ 2 #
+ 3 # Uses syntax sugar for:
+ 4 #   rm32 operands
+ 5 #   function calls
+ 6 #   control flow
+ 7 #
+ 8 # To run:
+ 9 #   $ ./translate_subx init.linux [01]*.subx apps/factorial.subx -o apps/factorial
+10 #   $ bootstrap/bootstrap run factorial
+11 # Expected result:
+12 #   $ echo $?
+13 #   120
+14 #
+15 # You can also run the automated test suite:
+16 #   $ bootstrap/bootstrap run factorial test
+17 # Expected output:
+18 #   ........
+19 # Every '.' indicates a passing test. Failing tests get a 'F'.
+20 #
+21 # Compare apps/factorial3.subx
+22 
+23 == code
+24 
+25 factorial:  # n: int -> _/eax: int
+26     # . prologue
+27     55/push-ebp
+28     89/<- %ebp 4/r32/esp
+29     # save registers
+30     51/push-ecx
+31     # if (n <= 1) return 1
+32     81 7/subop/compare *(ebp+8) 1/imm32
+33     {
+34       7f/jump-if-> break/disp8
+35       b8/copy-to-eax 1/imm32
+36       eb/jump $factorial:end/disp8
+37     }
+38     # n > 1; return n * factorial(n-1)
+39     8b/-> *(ebp+8) 1/r32/ecx
+40     49/decrement-ecx
+41     (factorial %ecx)  # => eax
+42     f7 4/subop/multiply-into-eax *(ebp+8)
+43     # TODO: check for overflow
+44 $factorial:end:
+45     # restore registers
+46     59/pop-to-ecx
+47     # . epilogue
+48     89/<- %esp 5/r32/ebp
+49     5d/pop-to-ebp
+50     c3/return
+51 
+52 test-factorial:
+53     (factorial 5)
+54     (check-ints-equal %eax 0x78 "F - test-factorial")
+55     c3/return
+56 
+57 Entry:  # run tests if necessary, compute `factorial(5)` if not
+58     # . prologue
+59     89/<- %ebp 4/r32/esp
+60 
+61     # initialize heap (needed by tests elsewhere)
+62     (new-segment *Heap-size Heap)
+63 
+64     # if (argc <= 1) return factorial(5)
+65     {
+66       # if (argc > 1) break
+67       81 7/subop/compare *ebp 1/imm32
+68       7f/jump-if-> break/disp8
+69       # ebx = factorial(5)
+70       (factorial 5)  # => eax
+71       89/<- %ebx 0/r32/eax
+72       eb/jump $main:end/disp8
+73     }
+74     # otherwise if first arg is "test", then return run_tests()
+75     {
+76       # if (!kernel-string-equal?(argv[1], "test")) break
+77       (kernel-string-equal? *(ebp+8) "test")  # => eax
+78       3d/compare-eax-and 0/imm32/false
+79       74/jump-if-= break/disp8
+80       #
+81       (run-tests)
+82       # exit(*Num-test-failures)
+83       8b/-> *Num-test-failures 3/r32/ebx
+84       eb/jump $main:end/disp8
+85     }
+86     bb/copy-to-ebx 0/imm32
+87 $main:end:
+88     e8/call  syscall_exit/disp32
+
+ + + -- cgit 1.4.1-2-gfad0