From bf02a19d02f24049e828fbc3fff36be348a44382 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sat, 31 Aug 2019 22:18:24 -0700 Subject: 5596 --- html/apps/factorial.subx.html | 196 +++++++++++++++++++++--------------------- 1 file changed, 100 insertions(+), 96 deletions(-) (limited to 'html/apps') diff --git a/html/apps/factorial.subx.html b/html/apps/factorial.subx.html index c02a7615..f8e53ba6 100644 --- a/html/apps/factorial.subx.html +++ b/html/apps/factorial.subx.html @@ -80,102 +80,106 @@ if ('onhashchange' in window) { 19 # . 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 20 21 Entry: # run tests if necessary, compute `factorial(5)` if not - 22 # initialize heap - 23 # . Heap = new-segment(64KB) - 24 # . . push args - 25 68/push Heap/imm32 - 26 68/push 0x10000/imm32/64KB - 27 # . . call - 28 e8/call new-segment/disp32 - 29 # . . discard args - 30 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 31 - 32 # . prolog - 33 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - 34 # - if argc > 1 and argv[1] == "test", then return run_tests() - 35 # . argc > 1 - 36 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 0/disp8 1/imm32 # compare *ebp - 37 7e/jump-if-lesser-or-equal $run-main/disp8 - 38 # . argv[1] == "test" - 39 # . . push args - 40 68/push "test"/imm32 - 41 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) - 42 # . . call - 43 e8/call kernel-string-equal?/disp32 - 44 # . . discard args - 45 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 46 # . check result - 47 3d/compare-eax-and 1/imm32 - 48 75/jump-if-not-equal $run-main/disp8 - 49 # . run-tests() - 50 e8/call run-tests/disp32 - 51 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/eax Num-test-failures/disp32 # copy *Num-test-failures to eax - 52 eb/jump $main:end/disp8 # where eax will get copied to ebx - 53 $run-main: - 54 # - otherwise return factorial(5) - 55 # . . push args - 56 68/push 5/imm32 - 57 # . . call - 58 e8/call factorial/disp32 - 59 # . . discard args - 60 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 61 $main:end: - 62 # syscall(exit, eax) - 63 89/copy 3/mod/direct 3/rm32/ebx . . . 0/r32/eax . . # copy eax to ebx - 64 b8/copy-to-eax 1/imm32/exit - 65 cd/syscall 0x80/imm8 - 66 - 67 factorial: # n : int -> int/eax - 68 # . prolog - 69 55/push-ebp - 70 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - 71 53/push-ebx - 72 # eax = 1 (base case) - 73 b8/copy-to-eax 1/imm32 - 74 # if (n <= 1) return - 75 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 1/imm32 # compare *(ebp+8) - 76 7e/jump-if-<= $factorial:end/disp8 - 77 # ebx = n-1 - 78 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 3/r32/ebx 8/disp8 . # copy *(ebp+8) to ebx - 79 81 5/subop/subtract 3/mod/direct 3/rm32/ebx . . . . . 1/imm32 # subtract from ebx - 80 # eax = factorial(n-1) - 81 # . . push args - 82 53/push-ebx - 83 # . . call - 84 e8/call factorial/disp32 - 85 # . . discard args - 86 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 87 # return n * factorial(n-1) - 88 f7 4/subop/multiply 1/mod/*+disp8 5/rm32/ebp . . 8/disp8 . # multiply *(ebp+8) into eax - 89 # TODO: check for overflow - 90 $factorial:end: - 91 # . epilog - 92 5b/pop-to-ebx - 93 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp - 94 5d/pop-to-ebp - 95 c3/return - 96 - 97 test-factorial: - 98 # factorial(5) - 99 # . . push args -100 68/push 5/imm32 -101 # . . call -102 e8/call factorial/disp32 -103 # . . discard args -104 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -105 # check-ints-equal(eax, 120, msg) -106 # . . push args -107 68/push "F - test-factorial"/imm32 -108 68/push 0x78/imm32/expected-120 -109 50/push-eax -110 # . . call -111 e8/call check-ints-equal/disp32 -112 # . . discard args -113 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -114 # end -115 c3/return -116 -117 # . . vim:nowrap:textwidth=0 + 22 # . prolog + 23 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + 24 + 25 # initialize heap + 26 # . Heap = new-segment(64KB) + 27 # . . push args + 28 68/push Heap/imm32 + 29 68/push 0x10000/imm32/64KB + 30 # . . call + 31 e8/call new-segment/disp32 + 32 # . . discard args + 33 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 34 + 35 # - if argc > 1 and argv[1] == "test", then return run_tests() + 36 # if (argc <= 1) goto run-main + 37 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 0/disp8 1/imm32 # compare *ebp + 38 7e/jump-if-lesser-or-equal $run-main/disp8 + 39 # if (!kernel-string-equal?(argv[1], "test")) goto run-main + 40 # . eax = kernel-string-equal?(argv[1], "test") + 41 # . . push args + 42 68/push "test"/imm32 + 43 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) + 44 # . . call + 45 e8/call kernel-string-equal?/disp32 + 46 # . . discard args + 47 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 48 # . if (eax == 0) goto run-main + 49 3d/compare-eax-and 0/imm32 + 50 74/jump-if-equal $run-main/disp8 + 51 # run-tests() + 52 e8/call run-tests/disp32 + 53 # eax = *Num-test-failures + 54 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/eax Num-test-failures/disp32 # copy *Num-test-failures to eax + 55 # return + 56 eb/jump $main:end/disp8 # where eax will get copied to ebx + 57 $run-main: + 58 # - otherwise return factorial(5) + 59 # . . push args + 60 68/push 5/imm32 + 61 # . . call + 62 e8/call factorial/disp32 + 63 # . . discard args + 64 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 65 $main:end: + 66 # syscall(exit, eax) + 67 89/copy 3/mod/direct 3/rm32/ebx . . . 0/r32/eax . . # copy eax to ebx + 68 b8/copy-to-eax 1/imm32/exit + 69 cd/syscall 0x80/imm8 + 70 + 71 factorial: # n : int -> int/eax + 72 # . prolog + 73 55/push-ebp + 74 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + 75 53/push-ebx + 76 # eax = 1 (base case) + 77 b8/copy-to-eax 1/imm32 + 78 # if (n <= 1) return + 79 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 1/imm32 # compare *(ebp+8) + 80 7e/jump-if-<= $factorial:end/disp8 + 81 # ebx = n-1 + 82 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 3/r32/ebx 8/disp8 . # copy *(ebp+8) to ebx + 83 81 5/subop/subtract 3/mod/direct 3/rm32/ebx . . . . . 1/imm32 # subtract from ebx + 84 # eax = factorial(n-1) + 85 # . . push args + 86 53/push-ebx + 87 # . . call + 88 e8/call factorial/disp32 + 89 # . . discard args + 90 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 91 # return n * factorial(n-1) + 92 f7 4/subop/multiply 1/mod/*+disp8 5/rm32/ebp . . 8/disp8 . # multiply *(ebp+8) into eax + 93 # TODO: check for overflow + 94 $factorial:end: + 95 # . epilog + 96 5b/pop-to-ebx + 97 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp + 98 5d/pop-to-ebp + 99 c3/return +100 +101 test-factorial: +102 # factorial(5) +103 # . . push args +104 68/push 5/imm32 +105 # . . call +106 e8/call factorial/disp32 +107 # . . discard args +108 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +109 # check-ints-equal(eax, 120, msg) +110 # . . push args +111 68/push "F - test-factorial"/imm32 +112 68/push 0x78/imm32/expected-120 +113 50/push-eax +114 # . . call +115 e8/call check-ints-equal/disp32 +116 # . . discard args +117 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +118 # end +119 c3/return +120 +121 # . . vim:nowrap:textwidth=0 -- cgit 1.4.1-2-gfad0