diff options
-rw-r--r-- | subx/056trace.subx | 12 | ||||
-rwxr-xr-x | subx/apps/assort | bin | 25642 -> 25661 bytes | |||
-rwxr-xr-x | subx/apps/crenshaw2-1 | bin | 21316 -> 21335 bytes | |||
-rwxr-xr-x | subx/apps/crenshaw2-1b | bin | 21875 -> 21894 bytes | |||
-rwxr-xr-x | subx/apps/factorial | bin | 20232 -> 20251 bytes | |||
-rwxr-xr-x | subx/apps/handle | bin | 21038 -> 21057 bytes | |||
-rwxr-xr-x | subx/apps/hex | bin | 24325 -> 24344 bytes | |||
-rwxr-xr-x | subx/apps/pack | bin | 40556 -> 40575 bytes | |||
-rwxr-xr-x | subx/apps/survey | bin | 22055 -> 23888 bytes | |||
-rw-r--r-- | subx/apps/survey.subx | 283 |
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 |