From 4c37b3e91b3e9c891c22379f029c42abc38e408c Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sun, 28 Oct 2018 13:41:53 -0700 Subject: 4734 --- html/subx/apps/crenshaw2-1.subx.html | 188 +++++++++++++++++++---------------- html/subx/apps/factorial.subx.html | 10 +- 2 files changed, 105 insertions(+), 93 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 5bd1da84..c848a55f 100644 --- a/html/subx/apps/crenshaw2-1.subx.html +++ b/html/subx/apps/crenshaw2-1.subx.html @@ -54,94 +54,106 @@ 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   # 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
+  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 crenshaw2-1
+  6 #   $ echo '3'  |./subx run apps/crenshaw2-1
+  7 # Expected output (not working yet):
+  8 #   # syscall(exit, 3)
+  9 #   bb/copy-to-EBX  3/imm32
+ 10 #   b8/copy-to-EAX  1/imm32/exit
+ 11 #   cd/syscall  0x80/imm8
+ 12 #
+ 13 # To run the generated output:
+ 14 #   $ echo '3'  |./subx run apps/crenshaw2-1 > z1.subx
+ 15 #   $ ./subx translate z1.subx -o z1
+ 16 #   $ ./subx run z1
+ 17 #   $ echo $?
+ 18 #   3
+ 19 #
+ 20 # Stdin must contain just a single hex number. Other input will print an error:
+ 21 #   $ echo 'xyz'  |./subx run apps/crenshaw2-1
+ 22 #   Error: integer expected
+ 23 
+ 24 == code
+ 25 # instruction                     effective address                                                   operand     displacement    immediate
+ 26 # op          subop               mod             rm32          base        index         scale       r32
+ 27 # 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
+ 28 
+ 29 # main:
+ 30   # allocate space for an exit-descriptor
+ 31   # var ed/EAX : (address exit-descriptor)
+ 32   81          5/subop/subtract    3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # subtract from ESP
+ 33   8d/copy-address                 0/mod/indirect  4/rm32/sib    4/base/ESP  4/index/none  .           0/r32/EAX   .               .                 # copy ESP to EAX
+ 34   # clear ed->target (so we really exit)
+ 35   c7/copy                         0/mod/direct    0/rm32/EAX    .           .             .           .           .               0/imm32           # copy to *EAX
+ 36   # expected(ed, 2/stderr, "integer")
+ 37     # push args
+ 38   68/push  "integer"/imm32
+ 39   68/push  2/imm32/stderr
+ 40   50/push-EAX
+ 41     # call
+ 42   e8/call  expected/disp32
+ 43     # discard args
+ 44   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+ 45   # syscall(exit, 0)
+ 46   bb/copy-to-EBX  0/imm32
+ 47   b8/copy-to-EAX  1/imm32/exit
+ 48   cd/syscall  0x80/imm8
+ 49 
+ 50 ## helpers
+ 51 
+ 52 expected:  # ed : (address exit-descriptor), f : fd or (address stream), s : (address array byte)
+ 53   # prolog
+ 54   55/push-EBP
+ 55   89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+ 56   # write(f, "Error: ")
+ 57     # push args
+ 58   68/push  "Error: "/imm32
+ 59   ff          6/subop/push        1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           .           0xc/disp8       .                 # push *(EBP+12)
+ 60     # call
+ 61   e8/call  write/disp32
+ 62     # discard args
+ 63   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+ 64   # write(f, s)
+ 65     # push args
+ 66   ff          6/subop/push        1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           .           0x10/disp8      .                 # push *(EBP+16)
+ 67   ff          6/subop/push        1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           .           0xc/disp8       .                 # push *(EBP+12)
+ 68     # call
+ 69   e8/call  write/disp32
+ 70     # discard args
+ 71   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+ 72   # write(f, " expected")
+ 73     # push args
+ 74   68/push  " expected"/imm32
+ 75   ff          6/subop/push        1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           .           0xc/disp8       .                 # push *(EBP+12)
+ 76     # call
+ 77   e8/call  write/disp32
+ 78     # discard args
+ 79   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+ 80   # write(f, Newline)
+ 81     # push args
+ 82   68/push  Newline/imm32
+ 83   ff          6/subop/push        1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           .           0xc/disp8       .                 # push *(EBP+12)
+ 84     # call
+ 85   e8/call  write/disp32
+ 86     # discard args
+ 87   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+ 88   # stop(ed, 1)
+ 89     # push args
+ 90   68/push  1/imm32
+ 91   ff          6/subop/push        1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           .           8/disp8         .                 # push *(EBP+8)
+ 92     # call
+ 93   e8/call  stop/disp32
+ 94   ## should never get past this point
+ 95   # epilog
+ 96   89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+ 97   5d/pop-to-EBP
+ 98   c3/return
+ 99 
+100 # vim:nowrap:textwidth=0
 
diff --git a/html/subx/apps/factorial.subx.html b/html/subx/apps/factorial.subx.html index 8e65e9cc..a30495cb 100644 --- a/html/subx/apps/factorial.subx.html +++ b/html/subx/apps/factorial.subx.html @@ -98,11 +98,11 @@ if ('onhashchange' in window) { 42 eb/jump $main:end/disp8 # where EAX will get copied to EBX 43 # else EAX = factorial(5) 44 $run-main: - 45 # push arg + 45 # push args 46 68/push 5/imm32 47 # call 48 e8/call factorial/disp32 - 49 # discard arg + 49 # discard args 50 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP 51 $main:end: 52 # exit(EAX) @@ -129,7 +129,7 @@ if ('onhashchange' in window) { 73 53/push-EBX 74 # call 75 e8/call factorial/disp32 - 76 # discard arg + 76 # discard args 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 @@ -143,11 +143,11 @@ if ('onhashchange' in window) { 87 88 test-factorial: 89 # factorial(5) - 90 # push arg + 90 # push args 91 68/push 5/imm32 92 # call 93 e8/call factorial/disp32 - 94 # discard arg + 94 # discard args 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 -- cgit 1.4.1-2-gfad0