From 104e521c04d1a0cad9c68fb11e250e12ad8917ef Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Wed, 17 Oct 2018 07:08:47 -0700 Subject: 4709 --- html/subx/apps/crenshaw2-1.subx.html | 203 +++++++++++++++-------------------- html/subx/apps/factorial.subx.html | 147 ++++++++++++------------- 2 files changed, 162 insertions(+), 188 deletions(-) (limited to 'html/subx/apps') diff --git a/html/subx/apps/crenshaw2-1.subx.html b/html/subx/apps/crenshaw2-1.subx.html index 8ac601ec..1ff68646 100644 --- a/html/subx/apps/crenshaw2-1.subx.html +++ b/html/subx/apps/crenshaw2-1.subx.html @@ -54,121 +54,94 @@ if ('onhashchange' in window) {
-  1 ## port of https://github.com/akkartik/crenshaw/blob/master/tutor2.1.pas
-  2 # corresponds to the section "single digits" in https://compilers.iecc.com/crenshaw/tutor2.txt
-  3 #
-  4 # To run (from the subx directory):
-  5 #   $ subx translate *.subx apps/crenshaw2.1.subx -o crenshaw 2.1
-  6 #   $ echo '3'  |subx run apps/crenshaw2.1  |xxd -
-  7 # Expected output:
-  8 #   TODO
-  9 #
- 10 # The output is the code a function would need to include, returning the
- 11 # result in EAX.
- 12 #
- 13 # Major note: byte strings are not null-terminated. Instead they're prefixed
- 14 # with a 32-bit length.
- 15 
- 16 == code
- 17 # instruction                     effective address                                                   operand     displacement    immediate
- 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 # main:
- 22   # abort("Integer")
- 23     # push args
- 24   68/push  "Integer"/imm32
- 25     # call
- 26   e8/call  abort/disp32
- 27     # discard arg
- 28   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
- 29   # exit(0)
- 30   bb/copy                         .               .             .           .             .           .           .               0/imm32           # copy to EBX
- 31   b8/copy                         .               .             .           .             .           .           .               1/imm32/exit      # copy to EAX
- 32   cd/syscall  0x80/imm8
- 33 
- 34 ## helpers
- 35 
- 36 # print error message and exit
- 37 # really maps to the 'Expected' function in Crenshaw
- 38 abort:  # s : (address array byte) -> <void>
- 39   # error(s)
- 40     # push args
- 41   ff          6/subop/push        1/mod/*+disp8   4/rm32/sib    4/base/ESP  4/index/none  .           .           4/disp8         .                 # push *(ESP+4)
- 42     # call
- 43   e8/call  error/disp32
- 44     # discard arg
- 45   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
- 46   # exit(1)
- 47   bb/copy                         .               .             .           .             .           .           .               1/imm32           # copy to EBX
- 48   b8/copy                         .               .             .           .             .           .           .               1/imm32/exit      # copy to EAX
- 49   cd/syscall  0x80/imm8
- 50 
- 51 # print out "Error: #{s} expected\n" to stderr
- 52 error:  # s : (address array byte) -> <void>
- 53   # write_stderr("Error: ")
- 54     # push args
- 55   68/push  "Error: "/imm32
- 56     # call
- 57   e8/call  write_stderr/disp32
- 58     # discard arg
- 59   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
- 60   # write_stderr(s)
- 61     # push args
- 62   ff          6/subop/push        1/mod/*+disp8   4/rm32/sib    4/base/ESP  4/index/none  .           .           4/disp8         .                 # push *(ESP+4)
- 63     # call
- 64   e8/call  write_stderr/disp32
- 65     # discard arg
- 66   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
- 67   # write_stderr(" expected")
- 68     # push args
- 69   68/push  " expected"/imm32
- 70     # call
- 71   e8/call  write_stderr/disp32
- 72     # discard arg
- 73   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
- 74   # write_stderr("\n")
- 75     # push args
- 76   68/push  Newline/imm32
- 77     # call
- 78   e8/call  write_stderr/disp32
- 79     # discard arg
- 80   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
- 81   # end
- 82   c3/return
- 83 
- 84 write_stdout:  # s : (address array byte) -> <void>
- 85   # prolog
- 86   55/push-EBP
- 87   89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
- 88   # save registers
- 89   50/push-EAX
- 90   51/push-ECX
- 91   52/push-EDX
- 92   53/push-EBX
- 93   # write(1/stdout, (data) s+4, (size) *s)
- 94     # fd = 1 (stdout)
- 95   bb/copy                         .               .             .           .             .           .           .               1/imm32           # copy to EBX
- 96     # x = s+4
- 97   8b/copy                         1/mod/*+disp8   4/rm32/SIB    5/base/EBP  4/index/none  .           1/r32/ECX   8/disp8         .                 # copy *(EBP+8) to ECX
- 98   81          0/subop/add         3/mod/direct    1/rm32/ECX    .           .             .           .           .               4/imm32           # add to ECX
- 99     # size = *s
-100   8b/copy                         1/mod/*+disp8   4/rm32/SIB    5/base/EBP  4/index/none  .           2/r32/EDX   8/disp8         .                 # copy *(EBP+8) to EDX
-101   8b/copy                         0/mod/indirect  2/rm32/EDX    .           .             .           2/r32/EDX   .               .                 # copy *EDX to EDX
-102     # call write()
-103   b8/copy                         .               .             .           .             .           .           .               4/imm32/write     # copy to EAX
-104   cd/syscall  0x80/imm8
-105   # restore registers
-106   5b/pop-to-EBX
-107   5a/pop-to-EDX
-108   59/pop-to-ECX
-109   58/pop-to-EAX
-110   # end
-111   89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
-112   5d/pop-to-EBP
-113   c3/return
-114 
-115 # vim:ft=subx:nowrap:so=0
+ 1 ## port of https://github.com/akkartik/crenshaw/blob/master/tutor2.1.pas
+ 2 # corresponds to the section "single digits" in https://compilers.iecc.com/crenshaw/tutor2.txt
+ 3 #
+ 4 # To run (from the subx directory):
+ 5 #   $ subx translate *.subx apps/crenshaw2.1.subx -o crenshaw 2.1
+ 6 #   $ echo '3'  |subx run apps/crenshaw2.1  |xxd -
+ 7 # Expected output:
+ 8 #   TODO
+ 9 #
+10 # The output is the code a function would need to include, returning the
+11 # result in EAX.
+12 #
+13 # Major note: byte strings are not null-terminated. Instead they're prefixed
+14 # with a 32-bit length.
+15 
+16 == code
+17 # instruction                     effective address                                                   operand     displacement    immediate
+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 # main:
+22   # abort("Integer")
+23     # push args
+24   68/push  "Integer"/imm32
+25     # call
+26   e8/call  abort/disp32
+27     # discard arg
+28   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+29   # syscall(exit, 0)
+30   bb/copy-to-EBX  0/imm32
+31   b8/copy-to-EAX  1/imm32/exit
+32   cd/syscall  0x80/imm8
+33 
+34 ## helpers
+35 
+36 # print error message and exit
+37 # really maps to the 'Expected' function in Crenshaw
+38 abort:  # s : (address array byte) -> <void>
+39   # error(s)
+40     # push args
+41   ff          6/subop/push        1/mod/*+disp8   4/rm32/sib    4/base/ESP  4/index/none  .           .           4/disp8         .                 # push *(ESP+4)
+42     # call
+43   e8/call  error/disp32
+44     # discard arg
+45   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+46   # syscall(exit, 1)
+47   bb/copy-to-EBX  1/imm32
+48   b8/copy-to-EAX  1/imm32/exit
+49   cd/syscall  0x80/imm8
+50 
+51 # print out "Error: #{s} expected\n" to stderr
+52 error:  # s : (address array byte) -> <void>
+53   # _write(2/stderr, "Error: ")
+54     # push args
+55   68/push  "Error: "/imm32
+56   68/push  2/imm32/stderr
+57     # call
+58   e8/call  _write/disp32
+59     # discard arg
+60   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+61   # _write(2/stderr, s)
+62     # push args
+63   ff          6/subop/push        1/mod/*+disp8   4/rm32/sib    4/base/ESP  4/index/none  .           .           4/disp8         .                 # push *(ESP+4)
+64   68/push  2/imm32/stderr
+65     # call
+66   e8/call  _write/disp32
+67     # discard arg
+68   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+69   # _write(2/stderr, " expected")
+70     # push args
+71   68/push  " expected"/imm32
+72   68/push  2/imm32/stderr
+73     # call
+74   e8/call  _write/disp32
+75     # discard arg
+76   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+77   # _write(2/stderr, "\n")
+78     # push args
+79   68/push  Newline/imm32
+80   68/push  2/imm32/stderr
+81     # call
+82   e8/call  _write/disp32
+83     # discard arg
+84   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+85   # end
+86   c3/return
+87 
+88 # vim:nowrap:textwidth=0
 
diff --git a/html/subx/apps/factorial.subx.html b/html/subx/apps/factorial.subx.html index 7111a908..8e65e9cc 100644 --- a/html/subx/apps/factorial.subx.html +++ b/html/subx/apps/factorial.subx.html @@ -79,88 +79,89 @@ if ('onhashchange' in window) { 23 # prolog 24 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP 25 # if (argc > 1) - 26 81 7/subop/compare 1/mod/*+disp8 4/rm32/SIB 5/base/EBP 4/index/none . . 0/disp8 1/imm32 # compare *EBP - 27 7e/jump-if-lesser-or-equal $run_main/disp8 + 26 81 7/subop/compare 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0/disp8 1/imm32 # compare *EBP + 27 7e/jump-if-lesser-or-equal $run-main/disp8 28 # and if (argv[1] == "test") 29 # push args 30 68/push "test"/imm32 31 ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0x8/disp8 . # push *(EBP+8) 32 # call - 33 e8/call kernel_string_equal/disp32 + 33 e8/call kernel-string-equal/disp32 34 # discard args 35 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP 36 # check result 37 3d/compare-EAX 1/imm32 - 38 75/jump-if-not-equal $run_main/disp8 - 39 # then - 40 e8/call run_tests/disp32 - 41 eb/jump $main_exit/disp8 - 42 # else EAX = factorial(5) - 43 $run_main: - 44 # push arg - 45 68/push 5/imm32 - 46 # call - 47 e8/call factorial/disp32 - 48 # discard arg - 49 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 50 $main_exit: - 51 # exit(EAX) - 52 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX - 53 b8/copy . . . . . . . 1/imm32 # copy to EAX - 54 cd/syscall 0x80/imm8 - 55 - 56 # factorial(n) - 57 factorial: - 58 # prolog - 59 55/push-EBP - 60 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - 61 53/push-EBX - 62 # initialize EAX to 1 (base case) - 63 b8/copy . . . . . . . 1/imm32 # copy to EAX - 64 # if (n <= 1) jump exit - 65 81 7/subop/compare 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 8/disp8 1/imm32 # compare *(EBP+8) - 66 7e/jump-if-<= $factorial:exit/disp8 - 67 # EBX: n-1 - 68 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none 3/r32/EBX 8/disp8 . # copy *(EBP+8) to EBX - 69 81 5/subop/subtract 3/mod/direct 3/rm32/EBX . . . . . 1/imm32 # subtract from EBX - 70 # EAX = factorial(n-1) - 71 # push args - 72 53/push-EBX - 73 # call - 74 e8/call . . . . . . factorial/disp32 - 75 # discard arg - 76 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 77 # return n * factorial(n-1) - 78 f7 4/subop/multiply 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none 8/disp8 . # multiply *(EBP+8) into EAX - 79 # TODO: check for overflow - 80 $factorial:exit: - 81 # epilog - 82 5b/pop-to-EBX - 83 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP - 84 5d/pop-to-EBP - 85 c3/return - 86 - 87 test_factorial: - 88 # factorial(5) - 89 # push arg - 90 68/push 5/imm32 - 91 # call - 92 e8/call factorial/disp32 - 93 # discard arg - 94 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 95 # check_ints_equal(EAX, 120, failure message) - 96 # push args - 97 68/push "F - test_factorial"/imm32 - 98 68/push 0x78/imm32/expected-120 - 99 50/push-EAX -100 # call -101 e8/call check_ints_equal/disp32 -102 # discard args -103 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -104 # end -105 c3/return -106 -107 # vim:ft=subx:nowrap:so=0 + 38 75/jump-if-not-equal $run-main/disp8 + 39 # then return run-tests() + 40 e8/call run-tests/disp32 + 41 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/EAX Num-test-failures/disp32 # copy *Num-test-failures to EAX + 42 eb/jump $main:end/disp8 # where EAX will get copied to EBX + 43 # else EAX = factorial(5) + 44 $run-main: + 45 # push arg + 46 68/push 5/imm32 + 47 # call + 48 e8/call factorial/disp32 + 49 # discard arg + 50 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 51 $main:end: + 52 # exit(EAX) + 53 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX + 54 b8/copy-to-EAX 1/imm32 + 55 cd/syscall 0x80/imm8 + 56 + 57 # factorial(n) + 58 factorial: + 59 # prolog + 60 55/push-EBP + 61 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP + 62 53/push-EBX + 63 # initialize EAX to 1 (base case) + 64 b8/copy-to-EAX 1/imm32 + 65 # if (n <= 1) jump exit + 66 81 7/subop/compare 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 8/disp8 1/imm32 # compare *(EBP+8) + 67 7e/jump-if-<= $factorial:end/disp8 + 68 # EBX = n-1 + 69 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none 3/r32/EBX 8/disp8 . # copy *(EBP+8) to EBX + 70 81 5/subop/subtract 3/mod/direct 3/rm32/EBX . . . . . 1/imm32 # subtract from EBX + 71 # EAX = factorial(n-1) + 72 # push args + 73 53/push-EBX + 74 # call + 75 e8/call factorial/disp32 + 76 # discard arg + 77 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 78 # return n * factorial(n-1) + 79 f7 4/subop/multiply 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none 8/disp8 . # multiply *(EBP+8) into EAX + 80 # TODO: check for overflow + 81 $factorial:end: + 82 # epilog + 83 5b/pop-to-EBX + 84 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP + 85 5d/pop-to-EBP + 86 c3/return + 87 + 88 test-factorial: + 89 # factorial(5) + 90 # push arg + 91 68/push 5/imm32 + 92 # call + 93 e8/call factorial/disp32 + 94 # discard arg + 95 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 96 # check-ints-equal(EAX, 120, failure message) + 97 # push args + 98 68/push "F - test-factorial"/imm32 + 99 68/push 0x78/imm32/expected-120 +100 50/push-EAX +101 # call +102 e8/call check-ints-equal/disp32 +103 # discard args +104 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +105 # end +106 c3/return +107 +108 # vim:nowrap:textwidth=0 -- cgit 1.4.1-2-gfad0