about summary refs log tree commit diff stats
path: root/subx
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2019-03-20 23:34:47 -0700
committerKartik Agaram <vc@akkartik.com>2019-03-20 23:34:47 -0700
commitedabbc3ca0a50ebb2ba4467000715d3259b18230 (patch)
tree22c686f8d87530a9bfb65ed3745dfa0a62abc424 /subx
parent19aca82c249666fcc679f61dd3f8250e1f373e5c (diff)
downloadmu-edabbc3ca0a50ebb2ba4467000715d3259b18230.tar.gz
5013
Diffstat (limited to 'subx')
-rwxr-xr-xsubx/apps/packbin21327 -> 21867 bytes
-rw-r--r--subx/apps/pack.subx230
2 files changed, 201 insertions, 29 deletions
diff --git a/subx/apps/pack b/subx/apps/pack
index 9b261693..bb14d36e 100755
--- a/subx/apps/pack
+++ b/subx/apps/pack
Binary files differdiff --git a/subx/apps/pack.subx b/subx/apps/pack.subx
index 9156f965..7f7288ce 100644
--- a/subx/apps/pack.subx
+++ b/subx/apps/pack.subx
@@ -143,7 +143,7 @@ $convert:loop:
 $convert:check0:
     # if (line->write == 0) break
     81          7/subop/compare     0/mod/indirect  1/rm32/ECX    .           .             .           .           .               0/imm32           # compare *ECX
-    74/jump-if-equal  $convert:break/disp8
+    0f 84/jump-if-equal  $convert:break/disp32
     # next-word(line, word-slice)
     # . . push args
     52/push-EDX
@@ -198,14 +198,29 @@ $convert:check2:
     # . goto pass-through
     eb/jump  $convert:pass-through/disp8
 $convert:check3:
-#?     # convert-instruction(line, out)
-#?     # . . push args
-#?     ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           0xc/disp8       .                 # push *(EBP+12)
-#?     51/push-ECX
-#?     # . . call
-#?     e8/call  convert-instruction/disp32
-#?     # . . discard args
-#?     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # else if (in-code? != 0) convert-instruction(line, out)
+    81          7/subop/compare     3/mod/direct    2/rm32/EBX    .           .             .           .           .               0/imm32           # compare EBX
+    74/jump-if-equal  $convert:check4/disp8
+    # . convert-instruction(line, out)
+    # . . push args
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           0xc/disp8       .                 # push *(EBP+12)
+    51/push-ECX
+    # . . call
+    e8/call  convert-instruction/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # . loop
+    e9/jump  $convert:loop/disp32
+$convert:check4:
+    # else convert-data(line, out)
+    # . . push args
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           0xc/disp8       .                 # push *(EBP+12)
+    51/push-ECX
+    # . . call
+    e8/call  convert-data/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # . loop
     e9/jump  $convert:loop/disp32
 $convert:pass-through:
     # write-stream-buffered(out, line)
@@ -460,29 +475,186 @@ test-convert-passes-segment-headers-through:
     5d/pop-to-EBP
     c3/return
 
-convert-code-segment:  # in : (address buffered-file), out : (address buffered-file) -> <void>
+convert-data:  # line : (address stream byte), out : (address buffered-file) -> <void>
     # pseudocode:
-    #   var line = new-stream(512, 1)
     #   while true
-    #     clear-stream(line)
-    #     EAX = read-line(in, line)
-    #     if (EAX == Eof) break
-    #     word-slice = next-word(line)
-    #     if slice-equal?(word-slice, "==")
-    #       return
-    #     convert-instruction(line, out)
+    #     word-slice = next-word
+    #     if (line->write == 0) break             # end of file
+    #     if slice-starts-with(word-slice, "#")       # comment
+    #       write-stream-buffered(out, line)
+    #     else if slice-ends-with(word-slice, ":")    # label
+    #       write-stream-buffered(out, line)
+    #     ...
+    #
+    # . prolog
+    55/push-EBP
+    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+    # . save registers
+    51/push-ECX
+    # var word-slice/ECX = {0, 0}
+    68/push  0/imm32/end
+    68/push  0/imm32/start
+    89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
+    # next-word(line, word-slice)
+    # . . push args
+    51/push-ECX
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           8/disp8         .                 # push *(EBP+8)
+    # . . call
+    e8/call  next-word/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+$convert-data:pass-line-through:
+    # write-stream-buffered(out, line)
+    # . . push args
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           8/disp8         .                 # push *(EBP+8)
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           0xc/disp8       .                 # push *(EBP+12)
+    # . . call
+    e8/call  write-stream-buffered/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+$convert-data:end:
+    # . restore registers
+    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
 
-convert-data-segment:  # in : (address buffered-file), out : (address buffered-file) -> <void>
-    # pseudocode:
-    #   var line = new-stream(512, 1)
-    #   while true
-    #     clear-stream(line)
-    #     EAX = read-line(in, line)
-    #     if (EAX == Eof) break
-    #     word-slice = next-word(line)
-    #     if slice-equal?(word-slice, "==")
-    #       return
-    #     convert-data-word(line, out)
+test-convert-data-passes-comments-through:
+    # if a line starts with '#', pass it along unchanged
+    # . 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-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-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, "# abcd")
+    # . . push args
+    68/push  "# abcd"/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-data(_test-input-stream, _test-output-buffered-file)
+    # . . push args
+    68/push  _test-output-buffered-file/imm32
+    68/push  _test-input-stream/imm32
+    # . . call
+    e8/call  convert-data/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # check that the write happened as expected
+    # . flush(_test-output-buffered-file)
+    # . . push args
+    68/push  _test-output-buffered-file/imm32
+    # . . call
+    e8/call  flush/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+    # . check-stream-equal(_test-output-stream, "# abcd", msg)
+    # . . push args
+    68/push  "F - test-convert-data-passes-comments-through"/imm32
+    68/push  "# abcd"/imm32
+    68/push  _test-output-stream/imm32
+    # . . call
+    e8/call  check-stream-equal/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+    # . epilog
+    89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+    5d/pop-to-EBP
+    c3/return
+
+test-convert-data-passes-labels-through:
+    # if the first word ends with ':', pass along the entire line unchanged
+    # . 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-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, "ab: # cd")
+    # . . push args
+    68/push  "ab: # cd"/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-data(_test-input-stream, _test-output-buffered-file)
+    # . . push args
+    68/push  _test-output-buffered-file/imm32
+    68/push  _test-input-stream/imm32
+    # . . call
+    e8/call  convert-data/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # check that the write happened as expected
+    # . flush(_test-output-buffered-file)
+    # . . push args
+    68/push  _test-output-buffered-file/imm32
+    # . . call
+    e8/call  flush/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+    # . check-stream-equal(_test-output-stream, "ab: # cd", msg)
+    # . . push args
+    68/push  "F - test-convert-data-passes-labels-through"/imm32
+    68/push  "ab: # cd"/imm32
+    68/push  _test-output-stream/imm32
+    # . . call
+    e8/call  check-stream-equal/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+    # . epilog
+    89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+    5d/pop-to-EBP
+    c3/return
 
 # - To pack an instruction, following the C++ version:
 # read first word as opcode and write-slice