about summary refs log tree commit diff stats
path: root/subx
diff options
context:
space:
mode:
Diffstat (limited to 'subx')
-rw-r--r--subx/056trace.subx12
-rwxr-xr-xsubx/apps/assortbin25642 -> 25661 bytes
-rwxr-xr-xsubx/apps/crenshaw2-1bin21316 -> 21335 bytes
-rwxr-xr-xsubx/apps/crenshaw2-1bbin21875 -> 21894 bytes
-rwxr-xr-xsubx/apps/factorialbin20232 -> 20251 bytes
-rwxr-xr-xsubx/apps/handlebin21038 -> 21057 bytes
-rwxr-xr-xsubx/apps/hexbin24325 -> 24344 bytes
-rwxr-xr-xsubx/apps/packbin40556 -> 40575 bytes
-rwxr-xr-xsubx/apps/surveybin22055 -> 23888 bytes
-rw-r--r--subx/apps/survey.subx283
10 files changed, 287 insertions, 8 deletions
diff --git a/subx/056trace.subx b/subx/056trace.subx
index 2e483bad..c8d7cc2c 100644
--- a/subx/056trace.subx
+++ b/subx/056trace.subx
@@ -24,6 +24,10 @@
 Trace-stream:
     0/imm32
 
+Trace-segment:
+    0/imm32/curr
+    0/imm32/end
+
 # Fake trace-stream for tests.
 # Also illustrates the layout of the real trace-stream (segment).
 _test-trace-stream:
@@ -52,14 +56,16 @@ initialize-trace-stream:  # n : int -> <void>
     51/push-ECX
     # ECX = n
     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           1/r32/ECX   8/disp8         .                 # copy *(EBP+8) to ECX
-    # EAX = new-segment(n)
+    # Trace-segment = new-segment(n)
     # . . push args
+    68/push  Trace-segment/imm32
     51/push-ECX
     # . . call
     e8/call  new-segment/disp32
     # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-    # copy EAX to *Trace-stream
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # copy Trace-segment->curr to *Trace-stream
+    8b/copy                         0/mod/indirect  5/rm32/.disp32            .             .           0/r32/EAX   Trace-segment/disp32              # copy *Trace-segment to EAX
     89/copy                         0/mod/indirect  5/rm32/.disp32            .             .           0/r32/EAX   Trace-stream/disp32               # copy EAX to *Trace-stream
     # Trace-stream->length = n - 12
     # . ECX -= 12
diff --git a/subx/apps/assort b/subx/apps/assort
index a53a3684..a37b8589 100755
--- a/subx/apps/assort
+++ b/subx/apps/assort
Binary files differdiff --git a/subx/apps/crenshaw2-1 b/subx/apps/crenshaw2-1
index d9b1a274..ba5de847 100755
--- a/subx/apps/crenshaw2-1
+++ b/subx/apps/crenshaw2-1
Binary files differdiff --git a/subx/apps/crenshaw2-1b b/subx/apps/crenshaw2-1b
index aa4a43ab..dd419629 100755
--- a/subx/apps/crenshaw2-1b
+++ b/subx/apps/crenshaw2-1b
Binary files differdiff --git a/subx/apps/factorial b/subx/apps/factorial
index f6636272..292fd7eb 100755
--- a/subx/apps/factorial
+++ b/subx/apps/factorial
Binary files differdiff --git a/subx/apps/handle b/subx/apps/handle
index dc69f189..5c815074 100755
--- a/subx/apps/handle
+++ b/subx/apps/handle
Binary files differdiff --git a/subx/apps/hex b/subx/apps/hex
index b634eb31..62dc2792 100755
--- a/subx/apps/hex
+++ b/subx/apps/hex
Binary files differdiff --git a/subx/apps/pack b/subx/apps/pack
index b64d93d7..407970b7 100755
--- a/subx/apps/pack
+++ b/subx/apps/pack
Binary files differdiff --git a/subx/apps/survey b/subx/apps/survey
index 477d476f..989c88c7 100755
--- a/subx/apps/survey
+++ b/subx/apps/survey
Binary files differdiff --git a/subx/apps/survey.subx b/subx/apps/survey.subx
index 186dea3a..aa6e53c1 100644
--- a/subx/apps/survey.subx
+++ b/subx/apps/survey.subx
@@ -2,7 +2,7 @@
 # (landscape).
 # Use the addresses assigned to:
 #   a) replace labels
-#   b) add segment headers containing the initial address
+#   b) add segment headers with addresses and offsets correctly filled in
 #
 # To build (from the subx/ directory):
 #   $ ./subx translate *.subx apps/survey.subx -o apps/survey
@@ -38,8 +38,7 @@
 # . 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
 
 Entry:
-    # initialize heap
-    # . Heap = new-segment(64KB)
+    # Heap = new-segment(64KB)
     # . . push args
     68/push  Heap/imm32
     68/push  0x10000/imm32/64KB
@@ -47,9 +46,16 @@ Entry:
     e8/call  new-segment/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # initialize-trace-stream(256KB)
+    # . . push args
+    68/push  0x40000/imm32/256KB
+    # . . call
+    e8/call  initialize-trace-stream/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
 
     # for debugging: run a single test
-#?     e8/call test-get-or-insert/disp32
+#?     e8/call test-convert-computes-addresses/disp32
 #?     8b/copy                         0/mod/indirect  5/rm32/.disp32            .             .           3/r32/EBX   Num-test-failures/disp32          # copy *Num-test-failures to EBX
 #?     eb/jump  $main:end/disp8
 
@@ -100,20 +106,287 @@ $main:end:
     b8/copy-to-EAX  1/imm32/exit
     cd/syscall  0x80/imm8
 
+# data structures:
+#   segment-info: {address, file-offset, size}            (12 bytes)
+#   segments: (address stream {string, segment-info})     (16 bytes per row)
+#   label-info: {segment-name, segment-offset, address}   (12 bytes)
+#   labels: (address stream {string, label-info})         (16 bytes per row)
+
 convert:  # in : (address buffered-file), out : (address buffered-file) -> <void>
+    # pseudocode
+    #   var segments = new-stream(10 rows, 16 bytes each)
+    #   var labels = new-stream(512 rows, 12 bytes each)
+    #   compute-offsets(in, segments, labels)
+    #   compute-addresses(segments, labels)
+    #   rewind-stream(in)
+    #   emit-output(in, out, segments, labels)
+    #
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
     # . save registers
+    51/push-ECX
+    52/push-EDX
+    # var segments/ECX = stream(10 * 16)
+    81          5/subop/subtract    3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xa0/imm32        # subtract from ESP
+    68/push  0xa0/imm32/length
+    68/push  0/imm32/read
+    68/push  0/imm32/write
+    89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
+    # var labels/EDX = stream(512 * 12)
+    81          5/subop/subtract    3/mod/direct    4/rm32/ESP    .           .             .           .           .               0x1800/imm32      # subtract from ESP
+    68/push  0x1800/imm32/length
+    68/push  0/imm32/read
+    68/push  0/imm32/write
+    89/copy                         3/mod/direct    2/rm32/EDX    .           .             .           4/r32/ESP   .               .                 # copy ESP to EDX
+    # compute-offsets(in, segments, labels)
+    # . . push args
+    52/push-EDX
+    51/push-ECX
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           8/disp8         .                 # push *(EBP+8)
+    # . . call
+    e8/call  compute-offsets/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+    # compute-addresses(segments, labels)
+    # . . push args
+    52/push-EDX
+    51/push-ECX
+    # . . call
+    e8/call  compute-addresses/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0x10/imm32        # add to ESP
+    # rewind-stream(in)
+    # . . push args
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           8/disp8         .                 # push *(EBP+8)
+    # . . call
+    e8/call  rewind-stream/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+    # emit-output(in, out, segments, labels)
+    # . . push args
+    52/push-EDX
+    51/push-ECX
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           0xc/disp8       .                 # push *(EBP+12)
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           8/disp8         .                 # push *(EBP+8)
+    # . . call
+    e8/call  emit-output/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0x10/imm32        # add to ESP
 $convert:end:
     # . reclaim locals
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0x214/imm32       # add to ESP
     # . restore registers
+    5a/pop-to-EDX
+    59/pop-to-ECX
     # . epilog
     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
     5d/pop-to-EBP
     c3/return
 
-## helpers
+test-convert-computes-addresses:
+    # input:
+    #   == code 0x1
+    #   ab x/imm32
+    #   == data 0x1000
+    #   x:
+    #     01
+    #
+    # trace contains (in any order):
+    #   label x is at address 0x1079
+    #   segment code starts at address 0x74
+    #   segment code has size 5
+    #   segment data starts at address 0x1079
+    #
+    # . prolog
+    55/push-EBP
+    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+    # setup
+    # . clear-stream(_test-input-stream)
+    # . . push args
+    68/push  _test-input-stream/imm32
+    # . . call
+    e8/call  clear-stream/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+    # . clear-stream(_test-input-buffered-file+4)
+    # . . push args
+    b8/copy-to-EAX  _test-input-buffered-file/imm32
+    05/add-to-EAX  4/imm32
+    50/push-EAX
+    # . . call
+    e8/call  clear-stream/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+    # . clear-stream(_test-output-stream)
+    # . . push args
+    68/push  _test-output-stream/imm32
+    # . . call
+    e8/call  clear-stream/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+    # . clear-stream(_test-output-buffered-file+4)
+    # . . push args
+    b8/copy-to-EAX  _test-output-buffered-file/imm32
+    05/add-to-EAX  4/imm32
+    50/push-EAX
+    # . . call
+    e8/call  clear-stream/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+    # initialize input
+    # . write(_test-input-stream, "== code 0x1\n")
+    # . . push args
+    68/push  "== code 0x1\n"/imm32
+    68/push  _test-input-stream/imm32
+    # . . call
+    e8/call  write/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # . write(_test-input-stream, "ab x/imm32\n")
+    # . . push args
+    68/push  "ab x/imm32\n"/imm32
+    68/push  _test-input-stream/imm32
+    # . . call
+    e8/call  write/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # . write(_test-input-stream, "== data 0x1000\n")
+    # . . push args
+    68/push  "== data 0x1000\n"/imm32
+    68/push  _test-input-stream/imm32
+    # . . call
+    e8/call  write/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # . write(_test-input-stream, "x:\n")
+    # . . push args
+    68/push  "x:\n"/imm32
+    68/push  _test-input-stream/imm32
+    # . . call
+    e8/call  write/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # . write(_test-input-stream, "01\n")
+    # . . push args
+    68/push  "01\n"/imm32
+    68/push  _test-input-stream/imm32
+    # . . call
+    e8/call  write/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # convert(_test-input-buffered-file, _test-output-buffered-file)
+    # . . push args
+    68/push  _test-output-buffered-file/imm32
+    68/push  _test-input-buffered-file/imm32
+    # . . call
+    e8/call  convert/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # check trace
+    # . check-trace-contains(Trace-stream, "label 'x' is at address 0x1079")
+    # . check-trace-contains(Trace-stream, "segment 'code' starts at address 0x74")
+    # . check-trace-contains(Trace-stream, "segment 'code' has size 0x5")
+    # . check-trace-contains(Trace-stream, "segment 'data' starts at address 0x1079")
+    # . epilog
+    89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+    5d/pop-to-EBP
+    c3/return
+
+compute-offsets:  # in : (address buffered-file), segments : (address stream {string, segment-info}), labels : (address stream {string, label-info})
+    # pseudocode:
+    #   gg
+    #
+    # . prolog
+    55/push-EBP
+    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+    # . save registers
+$compute-offsets:end:
+    # . reclaim locals
+    # . restore registers
+    # . epilog
+    89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+    5d/pop-to-EBP
+    c3/return
+
+test-compute-offsets:
+    # input:
+    #   == code 0x1
+    #   ab x/imm32
+    #   == data 0x1000
+    #   x:
+    #     01
+    #
+    # trace contains (in any order):
+    #   segment 'code' is at file offset 0
+    #   segment 'code' has size 5
+    #   segment 'data' is at file offset 5
+    #   label 'x' is in segment data
+    #   label 'x' is at offset 0
+    #   segment 'data' has size 1
+    #
+    # . prolog
+    55/push-EBP
+    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+    # setup
+    # . epilog
+    89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+    5d/pop-to-EBP
+    c3/return
+
+compute-addresses:  # segments : (address stream {string, segment-info}), labels : (address stream {string, label-info})
+    # pseudocode:
+    #
+    # . prolog
+    55/push-EBP
+    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+    # . save registers
+$compute-addresses:end:
+    # . reclaim locals
+    # . restore registers
+    # . epilog
+    89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+    5d/pop-to-EBP
+    c3/return
+
+test-compute-addresses:
+    # segment-info:
+    #   - {'a', 0x1000, 5, 0}
+    #   - {'b', 0x500, 1, 0}
+    #   - {'c', 0x5444, 12, 0}
+    # label-info:
+    #   - {'l1', 'code', 3, 0}
+    #   - {'l2', 'data', 0, 0}
+    #
+    # trace contains (in any order):
+    #   segment 'code starts at address 0x1074
+    #   segment 'data starts at address 0x579
+    #   label 'l1' is at address 0x1077
+    #   label 'l2' is at address 0x579
+    #
+    # . prolog
+    55/push-EBP
+    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+    # setup
+    # . epilog
+    89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+    5d/pop-to-EBP
+    c3/return
+
+emit-output:  # in : (address buffered-file), out : (address buffered-file), segments : (address stream {string, segment-info}), labels : (address stream {string, label-info})
+    # pseudocode:
+    #
+    # . prolog
+    55/push-EBP
+    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+    # . save registers
+$emit-output:end:
+    # . reclaim locals
+    # . restore registers
+    # . epilog
+    89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+    5d/pop-to-EBP
+    c3/return
 
 == data