diff options
Diffstat (limited to 'apps')
-rwxr-xr-x | apps/factorial | bin | 44976 -> 44976 bytes | |||
-rw-r--r-- | apps/factorial.mu | 5 | ||||
-rw-r--r-- | apps/factorial.subx | 100 | ||||
-rw-r--r-- | apps/factorial2.subx | 100 | ||||
-rw-r--r-- | apps/factorial3.subx | 59 | ||||
-rw-r--r-- | apps/factorial4.subx | 69 |
6 files changed, 171 insertions, 162 deletions
diff --git a/apps/factorial b/apps/factorial index c001d2d8..c5676040 100755 --- a/apps/factorial +++ b/apps/factorial Binary files differdiff --git a/apps/factorial.mu b/apps/factorial.mu index dab0ca90..362b68c6 100644 --- a/apps/factorial.mu +++ b/apps/factorial.mu @@ -8,6 +8,11 @@ # # You can also run the automated test suite: # $ ./a.elf test +# Expected output: +# ........ +# Every '.' indicates a passing test. Failing tests get a 'F'. +# There's only one test in this file, but you'll also see tests running from +# Mu's standard library. # # Compare apps/factorial4.subx diff --git a/apps/factorial.subx b/apps/factorial.subx index 74e4dd6d..b027696e 100644 --- a/apps/factorial.subx +++ b/apps/factorial.subx @@ -18,6 +18,55 @@ # . op subop mod rm32 base index scale r32 # . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes +factorial: # n: int -> int/eax + # . prologue + 55/push-ebp + 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + 53/push-ebx + # if (n <= 1) return 1 + b8/copy-to-eax 1/imm32 + 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 1/imm32 # compare *(ebp+8) + 7e/jump-if-<= $factorial:end/disp8 + # var ebx: int = n-1 + 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 3/r32/ebx 8/disp8 . # copy *(ebp+8) to ebx + 4b/decrement-ebx + # var eax: int = factorial(n-1) + # . . push args + 53/push-ebx + # . . call + e8/call factorial/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + # return n * factorial(n-1) + f7 4/subop/multiply 1/mod/*+disp8 5/rm32/ebp . . 8/disp8 . # multiply *(ebp+8) into eax + # TODO: check for overflow +$factorial:end: + # . epilogue + 5b/pop-to-ebx + 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp + 5d/pop-to-ebp + c3/return + +test-factorial: + # factorial(5) + # . . push args + 68/push 5/imm32 + # . . call + e8/call factorial/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + # check-ints-equal(eax, 120, msg) + # . . push args + 68/push "F - test-factorial"/imm32 + 68/push 0x78/imm32/expected-120 + 50/push-eax + # . . call + e8/call check-ints-equal/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + # end + c3/return + Entry: # run tests if necessary, compute `factorial(5)` if not # . prologue 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -92,58 +141,9 @@ $run-main: e8/call write/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # syscall(exit, eax) + # 89/copy 3/mod/direct 3/rm32/ebx . . . 0/r32/eax . . # copy eax to ebx $main:end: e8/call syscall_exit/disp32 -factorial: # n: int -> int/eax - # . prologue - 55/push-ebp - 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - 53/push-ebx - # if (n <= 1) return 1 - b8/copy-to-eax 1/imm32 - 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 1/imm32 # compare *(ebp+8) - 7e/jump-if-<= $factorial:end/disp8 - # var ebx: int = n-1 - 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 3/r32/ebx 8/disp8 . # copy *(ebp+8) to ebx - 4b/decrement-ebx - # var eax: int = factorial(n-1) - # . . push args - 53/push-ebx - # . . call - e8/call factorial/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # return n * factorial(n-1) - f7 4/subop/multiply 1/mod/*+disp8 5/rm32/ebp . . 8/disp8 . # multiply *(ebp+8) into eax - # TODO: check for overflow -$factorial:end: - # . epilogue - 5b/pop-to-ebx - 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp - 5d/pop-to-ebp - c3/return - -test-factorial: - # factorial(5) - # . . push args - 68/push 5/imm32 - # . . call - e8/call factorial/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # check-ints-equal(eax, 120, msg) - # . . push args - 68/push "F - test-factorial"/imm32 - 68/push 0x78/imm32/expected-120 - 50/push-eax - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - # end - c3/return - # . . vim:nowrap:textwidth=0 diff --git a/apps/factorial2.subx b/apps/factorial2.subx index 0eaaf049..7d303227 100644 --- a/apps/factorial2.subx +++ b/apps/factorial2.subx @@ -15,58 +15,11 @@ # Expected output: # ........ # Every '.' indicates a passing test. Failing tests get a 'F'. +# +# Compare apps/factorial.subx == code -Entry: # run tests if necessary, compute `factorial(5)` if not - # . prologue - 89/<- %ebp 4/r32/esp - - # initialize heap - # . Heap = new-segment(Heap-size) - # . . push args - 68/push Heap/imm32 - ff 6/subop/push *Heap-size - # . . call - e8/call new-segment/disp32 - # . . discard args - 81 0/subop/add %esp 8/imm32 - - # - if argc > 1 and argv[1] == "test", then return run_tests() - # if (argc <= 1) goto run-main - 81 7/subop/compare *ebp 1/imm32 - 7e/jump-if-<= $run-main/disp8 - # if (!kernel-string-equal?(argv[1], "test")) goto run-main - # . eax = kernel-string-equal?(argv[1], "test") - # . . push args - 68/push "test"/imm32 - ff 6/subop/push *(ebp+8) - # . . call - e8/call kernel-string-equal?/disp32 - # . . discard args - 81 0/subop/add %esp 8/imm32 - # . if (eax == false) goto run-main - 3d/compare-eax-and 0/imm32/false - 74/jump-if-= $run-main/disp8 - # run-tests() - e8/call run-tests/disp32 - # syscall(exit, *Num-test-failures) - 8b/-> *Num-test-failures 3/r32/ebx - eb/jump $main:end/disp8 -$run-main: - # - otherwise return factorial(5) - # eax = factorial(5) - # . . push args - 68/push 5/imm32 - # . . call - e8/call factorial/disp32 - # . . discard args - 81 0/subop/add %esp 4/imm32 - # syscall(exit, eax) - 89/<- %ebx 0/r32/eax -$main:end: - e8/call syscall_exit/disp32 - factorial: # n: int -> int/eax # . prologue 55/push-ebp @@ -115,3 +68,52 @@ test-factorial: 81 0/subop/add %esp 0xc/imm32 # end c3/return + +Entry: # run tests if necessary, compute `factorial(5)` if not + # . prologue + 89/<- %ebp 4/r32/esp + + # initialize heap + # . Heap = new-segment(Heap-size) + # . . push args + 68/push Heap/imm32 + ff 6/subop/push *Heap-size + # . . call + e8/call new-segment/disp32 + # . . discard args + 81 0/subop/add %esp 8/imm32 + + # - if argc > 1 and argv[1] == "test", then return run_tests() + # if (argc <= 1) goto run-main + 81 7/subop/compare *ebp 1/imm32 + 7e/jump-if-<= $run-main/disp8 + # if (!kernel-string-equal?(argv[1], "test")) goto run-main + # . eax = kernel-string-equal?(argv[1], "test") + # . . push args + 68/push "test"/imm32 + ff 6/subop/push *(ebp+8) + # . . call + e8/call kernel-string-equal?/disp32 + # . . discard args + 81 0/subop/add %esp 8/imm32 + # . if (eax == false) goto run-main + 3d/compare-eax-and 0/imm32/false + 74/jump-if-= $run-main/disp8 + # run-tests() + e8/call run-tests/disp32 + # syscall(exit, *Num-test-failures) + 8b/-> *Num-test-failures 3/r32/ebx + eb/jump $main:end/disp8 +$run-main: + # - otherwise return factorial(5) + # ebx = factorial(5) + # . . push args + 68/push 5/imm32 + # . . call + e8/call factorial/disp32 + # . . discard args + 81 0/subop/add %esp 4/imm32 + # + 89/<- %ebx 0/r32/eax +$main:end: + e8/call syscall_exit/disp32 diff --git a/apps/factorial3.subx b/apps/factorial3.subx index e8f39066..eb07b5ca 100644 --- a/apps/factorial3.subx +++ b/apps/factorial3.subx @@ -16,38 +16,11 @@ # Expected output: # ........ # Every '.' indicates a passing test. Failing tests get a 'F'. +# +# Compare apps/factorial2.subx == code -Entry: # run tests if necessary, compute `factorial(5)` if not - # . prologue - 89/<- %ebp 4/r32/esp - - # initialize heap - (new-segment *Heap-size Heap) - - # - if argc > 1 and argv[1] == "test", then return run_tests() - # if (argc <= 1) goto run-main - 81 7/subop/compare *ebp 1/imm32 - 7e/jump-if-<= $run-main/disp8 - # if (!kernel-string-equal?(argv[1], "test")) goto run-main - (kernel-string-equal? *(ebp+8) "test") # => eax - # . if (eax == false) goto run-main - 3d/compare-eax-and 0/imm32/false - 74/jump-if-= $run-main/disp8 - # - (run-tests) - # syscall(exit, *Num-test-failures) - 8b/-> *Num-test-failures 3/r32/ebx - eb/jump $main:end/disp8 -$run-main: - # - otherwise - (factorial 5) # => eax - # syscall(exit, eax) - 89/<- %ebx 0/r32/eax -$main:end: - e8/call syscall_exit/disp32 - factorial: # n: int -> int/eax # . prologue 55/push-ebp @@ -78,3 +51,31 @@ test-factorial: (factorial 5) (check-ints-equal %eax 0x78 "F - test-factorial") c3/return + +Entry: # run tests if necessary, compute `factorial(5)` if not + # . prologue + 89/<- %ebp 4/r32/esp + + # initialize heap (needed by tests elsewhere) + (new-segment *Heap-size Heap) + + # - if argc > 1 and argv[1] == "test", then return run_tests() + # if (argc <= 1) goto run-main + 81 7/subop/compare *ebp 1/imm32 + 7e/jump-if-<= $run-main/disp8 + # if (!kernel-string-equal?(argv[1], "test")) goto run-main + (kernel-string-equal? *(ebp+8) "test") # => eax + # . if (eax == false) goto run-main + 3d/compare-eax-and 0/imm32/false + 74/jump-if-= $run-main/disp8 + # + (run-tests) + # syscall(exit, *Num-test-failures) + 8b/-> *Num-test-failures 3/r32/ebx + eb/jump $main:end/disp8 +$run-main: + # - otherwise + (factorial 5) # => eax + 89/<- %ebx 0/r32/eax +$main:end: + e8/call syscall_exit/disp32 diff --git a/apps/factorial4.subx b/apps/factorial4.subx index 3028999e..6228f9ab 100644 --- a/apps/factorial4.subx +++ b/apps/factorial4.subx @@ -17,43 +17,11 @@ # Expected output: # ........ # Every '.' indicates a passing test. Failing tests get a 'F'. +# +# Compare apps/factorial3.subx == code -Entry: # run tests if necessary, compute `factorial(5)` if not - # . prologue - 89/<- %ebp 4/r32/esp - - # initialize heap - (new-segment *Heap-size Heap) - - # - if argc > 1, then return run_tests() - { - # if (argc <= 1) break - 81 7/subop/compare *ebp 1/imm32 - 7e/jump-if-<= break/disp8 - # if (!kernel-string-equal?(argv[1], "test")) break - (kernel-string-equal? *(ebp+8) "test") # => eax - 3d/compare-eax-and 0/imm32/false - 74/jump-if-= break/disp8 - # - (run-tests) - # eax = *Num-test-failures - 8b/-> *Num-test-failures 3/r32/ebx - } - # if (argc <= 1) factorial(5) - { - # if (argc > 1) break - 81 7/subop/compare *ebp 1/imm32 - 7f/jump-if-> break/disp8 - # eax = factorial(5) - (factorial 5) - # syscall(exit, eax) - 89/<- %ebx 0/r32/eax - } - - e8/call syscall_exit/disp32 - factorial: # n: int -> int/eax # . prologue 55/push-ebp @@ -86,3 +54,36 @@ test-factorial: (factorial 5) (check-ints-equal %eax 0x78 "F - test-factorial") c3/return + +Entry: # run tests if necessary, compute `factorial(5)` if not + # . prologue + 89/<- %ebp 4/r32/esp + + # initialize heap (needed by tests elsewhere) + (new-segment *Heap-size Heap) + + # if (argc <= 1) return factorial(5) + { + # if (argc > 1) break + 81 7/subop/compare *ebp 1/imm32 + 7f/jump-if-> break/disp8 + # ebx = factorial(5) + (factorial 5) # => eax + 89/<- %ebx 0/r32/eax + } + # otherwise if an arg exists and is "test", then return run_tests() + { + # if (argc <= 1) break + 81 7/subop/compare *ebp 1/imm32 + 7e/jump-if-<= break/disp8 + # if (!kernel-string-equal?(argv[1], "test")) break + (kernel-string-equal? *(ebp+8) "test") # => eax + 3d/compare-eax-and 0/imm32/false + 74/jump-if-= break/disp8 + # + (run-tests) + # ebx = *Num-test-failures + 8b/-> *Num-test-failures 3/r32/ebx + } + + e8/call syscall_exit/disp32 |