From 480fd9958abbd9b3b8443190ece755504cacdf9c Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Wed, 14 Oct 2020 13:42:03 -0700 Subject: 7032 --- html/apps/factorial.mu.html | 97 ++++++++-------- html/apps/factorial.subx.html | 254 ++++++++++++++++++++--------------------- html/apps/factorial2.subx.html | 200 ++++++++++++++++---------------- html/apps/factorial3.subx.html | 127 +++++++++++---------- html/apps/factorial4.subx.html | 140 +++++++++++------------ 5 files changed, 413 insertions(+), 405 deletions(-) (limited to 'html/apps') diff --git a/html/apps/factorial.mu.html b/html/apps/factorial.mu.html index b26c4123..823fcf3b 100644 --- a/html/apps/factorial.mu.html +++ b/html/apps/factorial.mu.html @@ -67,55 +67,60 @@ if ('onhashchange' in window) { 8 # 9 # You can also run the automated test suite: 10 # $ ./a.elf test -11 # -12 # Compare apps/factorial4.subx -13 -14 fn factorial n: int -> result/eax: int { -15 compare n, 1 -16 { -17 break-if-> -18 # n <= 1; return 1 -19 result <- copy 1 -20 } +11 # Expected output: +12 # ........ +13 # Every '.' indicates a passing test. Failing tests get a 'F'. +14 # There's only one test in this file, but you'll also see tests running from +15 # Mu's standard library. +16 # +17 # Compare apps/factorial4.subx +18 +19 fn factorial n: int -> result/eax: int { +20 compare n, 1 21 { -22 break-if-<= -23 # n > 1; return n * factorial(n-1) -24 var tmp/ecx: int <- copy n -25 tmp <- decrement -26 result <- factorial tmp -27 result <- multiply n -28 } -29 } -30 -31 fn test-factorial { -32 var result/eax: int <- factorial 5 -33 check-ints-equal result, 0x78, "F - test-factorial" +22 break-if-> +23 # n <= 1; return 1 +24 result <- copy 1 +25 } +26 { +27 break-if-<= +28 # n > 1; return n * factorial(n-1) +29 var tmp/ecx: int <- copy n +30 tmp <- decrement +31 result <- factorial tmp +32 result <- multiply n +33 } 34 } 35 -36 fn main args-on-stack: (addr array (addr array byte)) -> exit-status/ebx: int { -37 var args/eax: (addr array addr array byte) <- copy args-on-stack -38 # len = length(args) -39 var len/ecx: int <- length args -40 $main-body: { -41 # if (len <= 1) return factorial(5) -42 compare len, 1 -43 { -44 break-if-> -45 var tmp/eax: int <- factorial 5 -46 exit-status <- copy tmp -47 break $main-body -48 } -49 # if (args[1] == "test") run-tests() -50 var tmp2/ecx: (addr addr array byte) <- index args, 1 -51 var tmp3/eax: boolean <- string-equal? *tmp2, "test" -52 compare tmp3, 0 -53 { -54 break-if-= -55 run-tests -56 exit-status <- copy 0 # TODO: get at Num-test-failures somehow -57 } -58 } -59 } +36 fn test-factorial { +37 var result/eax: int <- factorial 5 +38 check-ints-equal result, 0x78, "F - test-factorial" +39 } +40 +41 fn main args-on-stack: (addr array (addr array byte)) -> exit-status/ebx: int { +42 var args/eax: (addr array addr array byte) <- copy args-on-stack +43 # len = length(args) +44 var len/ecx: int <- length args +45 $main-body: { +46 # if (len <= 1) return factorial(5) +47 compare len, 1 +48 { +49 break-if-> +50 var tmp/eax: int <- factorial 5 +51 exit-status <- copy tmp +52 break $main-body +53 } +54 # if (args[1] == "test") run-tests() +55 var tmp2/ecx: (addr addr array byte) <- index args, 1 +56 var tmp3/eax: boolean <- string-equal? *tmp2, "test" +57 compare tmp3, 0 +58 { +59 break-if-= +60 run-tests +61 exit-status <- copy 0 # TODO: get at Num-test-failures somehow +62 } +63 } +64 } diff --git a/html/apps/factorial.subx.html b/html/apps/factorial.subx.html index 9890611e..3d00b2d3 100644 --- a/html/apps/factorial.subx.html +++ b/html/apps/factorial.subx.html @@ -16,11 +16,11 @@ a { color:inherit; } * { font-size:12pt; font-size: 1em; } .subxComment { color: #005faf; } .subxS2Comment { color: #8a8a8a; } -.subxFunction { color: #af5f00; text-decoration: underline; } +.SpecialChar { color: #d70000; } .LineNr { } .subxTest { color: #5f8700; } .subxS1Comment { color: #0000af; } -.SpecialChar { color: #d70000; } +.subxFunction { color: #af5f00; text-decoration: underline; } .Normal { color: #000000; background-color: #c6c6c6; padding-bottom: 1px; } .Constant { color: #008787; } .subxH1Comment { color: #005faf; text-decoration: underline; } @@ -79,133 +79,133 @@ if ('onhashchange' in window) { 18 # . op subop mod rm32 base index scale r32 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 + 21 factorial: # n: int -> int/eax 22 # . prologue - 23 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - 24 - 25 # initialize heap - 26 # . Heap = new-segment(Heap-size) - 27 # . . push args - 28 68/push Heap/imm32 - 29 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Heap-size/disp32 # push *Heap-size - 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-<= $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 == false) goto run-main - 49 3d/compare-eax-and 0/imm32/false - 50 74/jump-if-= $run-main/disp8 - 51 # run-tests() - 52 e8/call run-tests/disp32 - 53 # syscall(exit, *Num-test-failures) - 54 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/ebx Num-test-failures/disp32 # copy *Num-test-failures to ebx - 55 eb/jump $main:end/disp8 - 56 $run-main: - 57 # - otherwise print factorial(5) - 58 # eax = factorial(5) + 23 55/push-ebp + 24 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + 25 53/push-ebx + 26 # if (n <= 1) return 1 + 27 b8/copy-to-eax 1/imm32 + 28 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 1/imm32 # compare *(ebp+8) + 29 7e/jump-if-<= $factorial:end/disp8 + 30 # var ebx: int = n-1 + 31 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 3/r32/ebx 8/disp8 . # copy *(ebp+8) to ebx + 32 4b/decrement-ebx + 33 # var eax: int = factorial(n-1) + 34 # . . push args + 35 53/push-ebx + 36 # . . call + 37 e8/call factorial/disp32 + 38 # . . discard args + 39 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 40 # return n * factorial(n-1) + 41 f7 4/subop/multiply 1/mod/*+disp8 5/rm32/ebp . . 8/disp8 . # multiply *(ebp+8) into eax + 42 # TODO: check for overflow + 43 $factorial:end: + 44 # . epilogue + 45 5b/pop-to-ebx + 46 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp + 47 5d/pop-to-ebp + 48 c3/return + 49 + 50 test-factorial: + 51 # factorial(5) + 52 # . . push args + 53 68/push 5/imm32 + 54 # . . call + 55 e8/call factorial/disp32 + 56 # . . discard args + 57 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 58 # check-ints-equal(eax, 120, msg) 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 # var buffer/ecx: (stream byte 10) # number of decimal digits a 32-bit number can have - 66 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa/imm32 # subtract from esp - 67 68/push 0xa/imm32/decimal-digits-in-32bit-number - 68 68/push 0/imm32/read - 69 68/push 0/imm32/write - 70 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - 71 # write-int32-decimal(buffer, eax) - 72 # . . push args - 73 50/push-eax - 74 51/push-ecx - 75 # . . call - 76 e8/call write-int32-decimal/disp32 - 77 # . . discard args - 78 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 79 # write-stream(stderr, buffer) - 80 # . . push args - 81 51/push-ecx - 82 68/push 2/imm32/stderr - 83 # . . call - 84 e8/call write-stream/disp32 - 85 # . . discard args - 86 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 87 # write(stderr, Newline) - 88 # . . push args - 89 68/push Newline/imm32 - 90 68/push 2/imm32/stderr - 91 # . . call - 92 e8/call write/disp32 - 93 # . . discard args - 94 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 95 # syscall(exit, eax) - 96 89/copy 3/mod/direct 3/rm32/ebx . . . 0/r32/eax . . # copy eax to ebx - 97 $main:end: - 98 e8/call syscall_exit/disp32 - 99 -100 factorial: # n: int -> int/eax -101 # . prologue -102 55/push-ebp -103 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -104 53/push-ebx -105 # if (n <= 1) return 1 -106 b8/copy-to-eax 1/imm32 -107 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 1/imm32 # compare *(ebp+8) -108 7e/jump-if-<= $factorial:end/disp8 -109 # var ebx: int = n-1 -110 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 3/r32/ebx 8/disp8 . # copy *(ebp+8) to ebx -111 4b/decrement-ebx -112 # var eax: int = factorial(n-1) -113 # . . push args -114 53/push-ebx -115 # . . call -116 e8/call factorial/disp32 -117 # . . discard args -118 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -119 # return n * factorial(n-1) -120 f7 4/subop/multiply 1/mod/*+disp8 5/rm32/ebp . . 8/disp8 . # multiply *(ebp+8) into eax -121 # TODO: check for overflow -122 $factorial:end: -123 # . epilogue -124 5b/pop-to-ebx -125 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -126 5d/pop-to-ebp -127 c3/return -128 -129 test-factorial: -130 # factorial(5) -131 # . . push args -132 68/push 5/imm32 -133 # . . call -134 e8/call factorial/disp32 -135 # . . discard args -136 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -137 # check-ints-equal(eax, 120, msg) -138 # . . push args -139 68/push "F - test-factorial"/imm32 -140 68/push 0x78/imm32/expected-120 -141 50/push-eax -142 # . . call -143 e8/call check-ints-equal/disp32 -144 # . . discard args -145 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -146 # end -147 c3/return + 60 68/push "F - test-factorial"/imm32 + 61 68/push 0x78/imm32/expected-120 + 62 50/push-eax + 63 # . . call + 64 e8/call check-ints-equal/disp32 + 65 # . . discard args + 66 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + 67 # end + 68 c3/return + 69 + 70 Entry: # run tests if necessary, compute `factorial(5)` if not + 71 # . prologue + 72 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + 73 + 74 # initialize heap + 75 # . Heap = new-segment(Heap-size) + 76 # . . push args + 77 68/push Heap/imm32 + 78 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Heap-size/disp32 # push *Heap-size + 79 # . . call + 80 e8/call new-segment/disp32 + 81 # . . discard args + 82 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 83 + 84 # - if argc > 1 and argv[1] == "test", then return run_tests() + 85 # if (argc <= 1) goto run-main + 86 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 0/disp8 1/imm32 # compare *ebp + 87 7e/jump-if-<= $run-main/disp8 + 88 # if (!kernel-string-equal?(argv[1], "test")) goto run-main + 89 # . eax = kernel-string-equal?(argv[1], "test") + 90 # . . push args + 91 68/push "test"/imm32 + 92 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) + 93 # . . call + 94 e8/call kernel-string-equal?/disp32 + 95 # . . discard args + 96 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 97 # . if (eax == false) goto run-main + 98 3d/compare-eax-and 0/imm32/false + 99 74/jump-if-= $run-main/disp8 +100 # run-tests() +101 e8/call run-tests/disp32 +102 # syscall(exit, *Num-test-failures) +103 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/ebx Num-test-failures/disp32 # copy *Num-test-failures to ebx +104 eb/jump $main:end/disp8 +105 $run-main: +106 # - otherwise print factorial(5) +107 # eax = factorial(5) +108 # . . push args +109 68/push 5/imm32 +110 # . . call +111 e8/call factorial/disp32 +112 # . . discard args +113 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +114 # var buffer/ecx: (stream byte 10) # number of decimal digits a 32-bit number can have +115 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa/imm32 # subtract from esp +116 68/push 0xa/imm32/decimal-digits-in-32bit-number +117 68/push 0/imm32/read +118 68/push 0/imm32/write +119 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +120 # write-int32-decimal(buffer, eax) +121 # . . push args +122 50/push-eax +123 51/push-ecx +124 # . . call +125 e8/call write-int32-decimal/disp32 +126 # . . discard args +127 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +128 # write-stream(stderr, buffer) +129 # . . push args +130 51/push-ecx +131 68/push 2/imm32/stderr +132 # . . call +133 e8/call write-stream/disp32 +134 # . . discard args +135 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +136 # write(stderr, Newline) +137 # . . push args +138 68/push Newline/imm32 +139 68/push 2/imm32/stderr +140 # . . call +141 e8/call write/disp32 +142 # . . discard args +143 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +144 # +145 89/copy 3/mod/direct 3/rm32/ebx . . . 0/r32/eax . . # copy eax to ebx +146 $main:end: +147 e8/call syscall_exit/disp32 148 149 # . . vim:nowrap:textwidth=0 diff --git a/html/apps/factorial2.subx.html b/html/apps/factorial2.subx.html index cf2478f8..295d7e0b 100644 --- a/html/apps/factorial2.subx.html +++ b/html/apps/factorial2.subx.html @@ -16,11 +16,11 @@ a { color:inherit; } * { font-size:12pt; font-size: 1em; } .subxComment { color: #005faf; } .subxS2Comment { color: #8a8a8a; } -.subxFunction { color: #af5f00; text-decoration: underline; } +.SpecialChar { color: #d70000; } .LineNr { } .subxTest { color: #5f8700; } .subxS1Comment { color: #0000af; } -.SpecialChar { color: #d70000; } +.subxFunction { color: #af5f00; text-decoration: underline; } .Constant { color: #008787; } .subxH1Comment { color: #005faf; text-decoration: underline; } --> @@ -75,106 +75,108 @@ if ('onhashchange' in window) { 15 # Expected output: 16 # ........ 17 # Every '.' indicates a passing test. Failing tests get a 'F'. - 18 - 19 == code + 18 # + 19 # Compare apps/factorial.subx 20 - 21 Entry: # run tests if necessary, compute `factorial(5)` if not - 22 # . prologue - 23 89/<- %ebp 4/r32/esp - 24 - 25 # initialize heap - 26 # . Heap = new-segment(Heap-size) - 27 # . . push args - 28 68/push Heap/imm32 - 29 ff 6/subop/push *Heap-size - 30 # . . call - 31 e8/call new-segment/disp32 - 32 # . . discard args - 33 81 0/subop/add %esp 8/imm32 - 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 *ebp 1/imm32 - 38 7e/jump-if-<= $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 *(ebp+8) - 44 # . . call - 45 e8/call kernel-string-equal?/disp32 - 46 # . . discard args - 47 81 0/subop/add %esp 8/imm32 - 48 # . if (eax == false) goto run-main - 49 3d/compare-eax-and 0/imm32/false - 50 74/jump-if-= $run-main/disp8 - 51 # run-tests() - 52 e8/call run-tests/disp32 - 53 # syscall(exit, *Num-test-failures) - 54 8b/-> *Num-test-failures 3/r32/ebx - 55 eb/jump $main:end/disp8 - 56 $run-main: - 57 # - otherwise return factorial(5) - 58 # eax = 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 %esp 4/imm32 - 65 # syscall(exit, eax) - 66 89/<- %ebx 0/r32/eax - 67 $main:end: - 68 e8/call syscall_exit/disp32 - 69 - 70 factorial: # n: int -> int/eax - 71 # . prologue - 72 55/push-ebp - 73 89/<- %ebp 4/r32/esp - 74 53/push-ebx - 75 # if (n <= 1) return 1 - 76 b8/copy-to-eax 1/imm32 - 77 81 7/subop/compare *(ebp+8) 1/imm32 - 78 7e/jump-if-<= $factorial:end/disp8 - 79 # var ebx: int = n-1 - 80 8b/-> *(ebp+8) 3/r32/ebx - 81 4b/decrement-ebx - 82 # var eax: int = factorial(n-1) - 83 # . . push args - 84 53/push-ebx - 85 # . . call - 86 e8/call factorial/disp32 - 87 # . . discard args - 88 81 0/subop/add %esp 4/imm32 - 89 # return n * factorial(n-1) - 90 f7 4/subop/multiply-into-eax *(ebp+8) - 91 # TODO: check for overflow - 92 $factorial:end: - 93 # . epilogue - 94 5b/pop-to-ebx - 95 89/<- %esp 5/r32/ebp - 96 5d/pop-to-ebp - 97 c3/return - 98 - 99 test-factorial: -100 # factorial(5) -101 # . . push args -102 68/push 5/imm32 -103 # . . call -104 e8/call factorial/disp32 -105 # . . discard args -106 81 0/subop/add %esp 4/imm32 -107 # check-ints-equal(eax, 120, msg) -108 # . . push args -109 68/push "F - test-factorial"/imm32 -110 68/push 0x78/imm32/expected-120 -111 50/push-eax + 21 == code + 22 + 23 factorial: # n: int -> int/eax + 24 # . prologue + 25 55/push-ebp + 26 89/<- %ebp 4/r32/esp + 27 53/push-ebx + 28 # if (n <= 1) return 1 + 29 b8/copy-to-eax 1/imm32 + 30 81 7/subop/compare *(ebp+8) 1/imm32 + 31 7e/jump-if-<= $factorial:end/disp8 + 32 # var ebx: int = n-1 + 33 8b/-> *(ebp+8) 3/r32/ebx + 34 4b/decrement-ebx + 35 # var eax: int = factorial(n-1) + 36 # . . push args + 37 53/push-ebx + 38 # . . call + 39 e8/call factorial/disp32 + 40 # . . discard args + 41 81 0/subop/add %esp 4/imm32 + 42 # return n * factorial(n-1) + 43 f7 4/subop/multiply-into-eax *(ebp+8) + 44 # TODO: check for overflow + 45 $factorial:end: + 46 # . epilogue + 47 5b/pop-to-ebx + 48 89/<- %esp 5/r32/ebp + 49 5d/pop-to-ebp + 50 c3/return + 51 + 52 test-factorial: + 53 # factorial(5) + 54 # . . push args + 55 68/push 5/imm32 + 56 # . . call + 57 e8/call factorial/disp32 + 58 # . . discard args + 59 81 0/subop/add %esp 4/imm32 + 60 # check-ints-equal(eax, 120, msg) + 61 # . . push args + 62 68/push "F - test-factorial"/imm32 + 63 68/push 0x78/imm32/expected-120 + 64 50/push-eax + 65 # . . call + 66 e8/call check-ints-equal/disp32 + 67 # . . discard args + 68 81 0/subop/add %esp 0xc/imm32 + 69 # end + 70 c3/return + 71 + 72 Entry: # run tests if necessary, compute `factorial(5)` if not + 73 # . prologue + 74 89/<- %ebp 4/r32/esp + 75 + 76 # initialize heap + 77 # . Heap = new-segment(Heap-size) + 78 # . . push args + 79 68/push Heap/imm32 + 80 ff 6/subop/push *Heap-size + 81 # . . call + 82 e8/call new-segment/disp32 + 83 # . . discard args + 84 81 0/subop/add %esp 8/imm32 + 85 + 86 # - if argc > 1 and argv[1] == "test", then return run_tests() + 87 # if (argc <= 1) goto run-main + 88 81 7/subop/compare *ebp 1/imm32 + 89 7e/jump-if-<= $run-main/disp8 + 90 # if (!kernel-string-equal?(argv[1], "test")) goto run-main + 91 # . eax = kernel-string-equal?(argv[1], "test") + 92 # . . push args + 93 68/push "test"/imm32 + 94 ff 6/subop/push *(ebp+8) + 95 # . . call + 96 e8/call kernel-string-equal?/disp32 + 97 # . . discard args + 98 81 0/subop/add %esp 8/imm32 + 99 # . if (eax == false) goto run-main +100 3d/compare-eax-and 0/imm32/false +101 74/jump-if-= $run-main/disp8 +102 # run-tests() +103 e8/call run-tests/disp32 +104 # syscall(exit, *Num-test-failures) +105 8b/-> *Num-test-failures 3/r32/ebx +106 eb/jump $main:end/disp8 +107 $run-main: +108 # - otherwise return factorial(5) +109 # ebx = factorial(5) +110 # . . push args +111 68/push 5/imm32 112 # . . call -113 e8/call check-ints-equal/disp32 +113 e8/call factorial/disp32 114 # . . discard args -115 81 0/subop/add %esp 0xc/imm32 -116 # end -117 c3/return +115 81 0/subop/add %esp 4/imm32 +116 # +117 89/<- %ebx 0/r32/eax +118 $main:end: +119 e8/call syscall_exit/disp32 diff --git a/html/apps/factorial3.subx.html b/html/apps/factorial3.subx.html index 2c522450..a61385fc 100644 --- a/html/apps/factorial3.subx.html +++ b/html/apps/factorial3.subx.html @@ -15,11 +15,11 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color: a { color:inherit; } * { font-size:12pt; font-size: 1em; } .subxComment { color: #005faf; } -.subxFunction { color: #af5f00; text-decoration: underline; } +.SpecialChar { color: #d70000; } .LineNr { } .subxTest { color: #5f8700; } .subxS1Comment { color: #0000af; } -.SpecialChar { color: #d70000; } +.subxFunction { color: #af5f00; text-decoration: underline; } .Constant { color: #008787; } .subxH1Comment { color: #005faf; text-decoration: underline; } --> @@ -75,68 +75,69 @@ if ('onhashchange' in window) { 16 # Expected output: 17 # ........ 18 # Every '.' indicates a passing test. Failing tests get a 'F'. -19 -20 == code +19 # +20 # Compare apps/factorial2.subx 21 -22 Entry: # run tests if necessary, compute `factorial(5)` if not -23 # . prologue -24 89/<- %ebp 4/r32/esp -25 -26 # initialize heap -27 (new-segment *Heap-size Heap) -28 -29 # - if argc > 1 and argv[1] == "test", then return run_tests() -30 # if (argc <= 1) goto run-main -31 81 7/subop/compare *ebp 1/imm32 -32 7e/jump-if-<= $run-main/disp8 -33 # if (!kernel-string-equal?(argv[1], "test")) goto run-main -34 (kernel-string-equal? *(ebp+8) "test") # => eax -35 # . if (eax == false) goto run-main -36 3d/compare-eax-and 0/imm32/false -37 74/jump-if-= $run-main/disp8 -38 # -39 (run-tests) -40 # syscall(exit, *Num-test-failures) -41 8b/-> *Num-test-failures 3/r32/ebx -42 eb/jump $main:end/disp8 -43 $run-main: -44 # - otherwise -45 (factorial 5) # => eax -46 # syscall(exit, eax) -47 89/<- %ebx 0/r32/eax -48 $main:end: -49 e8/call syscall_exit/disp32 -50 -51 factorial: # n: int -> int/eax -52 # . prologue -53 55/push-ebp -54 89/<- %ebp 4/r32/esp -55 # save registers -56 53/push-ebx -57 # if (n <= 1) return 1 -58 b8/copy-to-eax 1/imm32 -59 81 7/subop/compare *(ebp+8) 1/imm32 -60 7e/jump-if-<= $factorial:end/disp8 -61 # var ebx: int = n-1 -62 8b/-> *(ebp+8) 3/r32/ebx -63 4b/decrement-ebx -64 # -65 (factorial %ebx) # => eax -66 # return n * factorial(n-1) -67 f7 4/subop/multiply-into-eax *(ebp+8) -68 # TODO: check for overflow -69 $factorial:end: -70 # restore registers -71 5b/pop-to-ebx -72 # . epilogue -73 89/<- %esp 5/r32/ebp -74 5d/pop-to-ebp -75 c3/return -76 -77 test-factorial: -78 (factorial 5) -79 (check-ints-equal %eax 0x78 "F - test-factorial") -80 c3/return +22 == code +23 +24 factorial: # n: int -> int/eax +25 # . prologue +26 55/push-ebp +27 89/<- %ebp 4/r32/esp +28 # save registers +29 53/push-ebx +30 # if (n <= 1) return 1 +31 b8/copy-to-eax 1/imm32 +32 81 7/subop/compare *(ebp+8) 1/imm32 +33 7e/jump-if-<= $factorial:end/disp8 +34 # var ebx: int = n-1 +35 8b/-> *(ebp+8) 3/r32/ebx +36 4b/decrement-ebx +37 # +38 (factorial %ebx) # => eax +39 # return n * factorial(n-1) +40 f7 4/subop/multiply-into-eax *(ebp+8) +41 # TODO: check for overflow +42 $factorial:end: +43 # restore registers +44 5b/pop-to-ebx +45 # . epilogue +46 89/<- %esp 5/r32/ebp +47 5d/pop-to-ebp +48 c3/return +49 +50 test-factorial: +51 (factorial 5) +52 (check-ints-equal %eax 0x78 "F - test-factorial") +53 c3/return +54 +55 Entry: # run tests if necessary, compute `factorial(5)` if not +56 # . prologue +57 89/<- %ebp 4/r32/esp +58 +59 # initialize heap (needed by tests elsewhere) +60 (new-segment *Heap-size Heap) +61 +62 # - if argc > 1 and argv[1] == "test", then return run_tests() +63 # if (argc <= 1) goto run-main +64 81 7/subop/compare *ebp 1/imm32 +65 7e/jump-if-<= $run-main/disp8 +66 # if (!kernel-string-equal?(argv[1], "test")) goto run-main +67 (kernel-string-equal? *(ebp+8) "test") # => eax +68 # . if (eax == false) goto run-main +69 3d/compare-eax-and 0/imm32/false +70 74/jump-if-= $run-main/disp8 +71 # +72 (run-tests) +73 # syscall(exit, *Num-test-failures) +74 8b/-> *Num-test-failures 3/r32/ebx +75 eb/jump $main:end/disp8 +76 $run-main: +77 # - otherwise +78 (factorial 5) # => eax +79 89/<- %ebx 0/r32/eax +80 $main:end: +81 e8/call syscall_exit/disp32 diff --git a/html/apps/factorial4.subx.html b/html/apps/factorial4.subx.html index b40586bf..7c770ea7 100644 --- a/html/apps/factorial4.subx.html +++ b/html/apps/factorial4.subx.html @@ -15,13 +15,12 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color: a { color:inherit; } * { font-size:12pt; font-size: 1em; } .subxComment { color: #005faf; } -.subxFunction { color: #af5f00; text-decoration: underline; } +.SpecialChar { color: #d70000; } .LineNr { } .subxTest { color: #5f8700; } .subxS1Comment { color: #0000af; } -.SpecialChar { color: #d70000; } +.subxFunction { color: #af5f00; text-decoration: underline; } .Constant { color: #008787; } -.subxH1Comment { color: #005faf; text-decoration: underline; } --> @@ -76,75 +75,76 @@ if ('onhashchange' in window) { 17 # Expected output: 18 # ........ 19 # Every '.' indicates a passing test. Failing tests get a 'F'. -20 -21 == code +20 # +21 # Compare apps/factorial3.subx 22 -23 Entry: # run tests if necessary, compute `factorial(5)` if not -24 # . prologue -25 89/<- %ebp 4/r32/esp -26 -27 # initialize heap -28 (new-segment *Heap-size Heap) -29 -30 # - if argc > 1, then return run_tests() -31 { -32 # if (argc <= 1) break -33 81 7/subop/compare *ebp 1/imm32 -34 7e/jump-if-<= break/disp8 -35 # if (!kernel-string-equal?(argv[1], "test")) break -36 (kernel-string-equal? *(ebp+8) "test") # => eax -37 3d/compare-eax-and 0/imm32/false -38 74/jump-if-= break/disp8 -39 # -40 (run-tests) -41 # eax = *Num-test-failures -42 8b/-> *Num-test-failures 3/r32/ebx -43 } -44 # if (argc <= 1) factorial(5) -45 { -46 # if (argc > 1) break -47 81 7/subop/compare *ebp 1/imm32 -48 7f/jump-if-> break/disp8 -49 # eax = factorial(5) -50 (factorial 5) -51 # syscall(exit, eax) -52 89/<- %ebx 0/r32/eax -53 } -54 -55 e8/call syscall_exit/disp32 -56 -57 factorial: # n: int -> int/eax -58 # . prologue -59 55/push-ebp +23 == code +24 +25 factorial: # n: int -> int/eax +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 } +37 # if (n > 1) return n * factorial(n-1) +38 { +39 7e/jump-if-<= break/disp8 +40 # var tmp/ecx: int = n-1 +41 8b/-> *(ebp+8) 1/r32/ecx +42 49/decrement-ecx +43 (factorial %ecx) # => eax +44 f7 4/subop/multiply-into-eax *(ebp+8) +45 } +46 # restore registers +47 59/pop-to-ecx +48 # . epilogue +49 89/<- %esp 5/r32/ebp +50 5d/pop-to-ebp +51 c3/return +52 +53 test-factorial: +54 (factorial 5) +55 (check-ints-equal %eax 0x78 "F - test-factorial") +56 c3/return +57 +58 Entry: # run tests if necessary, compute `factorial(5)` if not +59 # . prologue 60 89/<- %ebp 4/r32/esp -61 # save registers -62 51/push-ecx -63 # if (n <= 1) return 1 -64 81 7/subop/compare *(ebp+8) 1/imm32 -65 { -66 7f/jump-if-> break/disp8 -67 b8/copy-to-eax 1/imm32 -68 } -69 # if (n > 1) return n * factorial(n-1) -70 { -71 7e/jump-if-<= break/disp8 -72 # var tmp/ecx: int = n-1 -73 8b/-> *(ebp+8) 1/r32/ecx -74 49/decrement-ecx -75 (factorial %ecx) # => eax -76 f7 4/subop/multiply-into-eax *(ebp+8) -77 } -78 # restore registers -79 59/pop-to-ecx -80 # . epilogue -81 89/<- %esp 5/r32/ebp -82 5d/pop-to-ebp -83 c3/return -84 -85 test-factorial: -86 (factorial 5) -87 (check-ints-equal %eax 0x78 "F - test-factorial") -88 c3/return +61 +62 # initialize heap (needed by tests elsewhere) +63 (new-segment *Heap-size Heap) +64 +65 # if (argc <= 1) return factorial(5) +66 { +67 # if (argc > 1) break +68 81 7/subop/compare *ebp 1/imm32 +69 7f/jump-if-> break/disp8 +70 # ebx = factorial(5) +71 (factorial 5) # => eax +72 89/<- %ebx 0/r32/eax +73 } +74 # otherwise if an arg exists and is "test", then return run_tests() +75 { +76 # if (argc <= 1) break +77 81 7/subop/compare *ebp 1/imm32 +78 7e/jump-if-<= break/disp8 +79 # if (!kernel-string-equal?(argv[1], "test")) break +80 (kernel-string-equal? *(ebp+8) "test") # => eax +81 3d/compare-eax-and 0/imm32/false +82 74/jump-if-= break/disp8 +83 # +84 (run-tests) +85 # ebx = *Num-test-failures +86 8b/-> *Num-test-failures 3/r32/ebx +87 } +88 +89 e8/call syscall_exit/disp32 -- cgit 1.4.1-2-gfad0