about summary refs log tree commit diff stats
path: root/subx/055stream.subx
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2019-02-02 22:05:11 -0800
committerKartik Agaram <vc@akkartik.com>2019-02-02 22:05:11 -0800
commit03c6f1d3858ff0fdb6af6ce4b61bea51f16b33be (patch)
tree2dfceaa7676f03f09dc3585030b56cdea834483d /subx/055stream.subx
parentcb82bd2364c302acbb96dd6900779e189b36efac (diff)
downloadmu-03c6f1d3858ff0fdb6af6ce4b61bea51f16b33be.tar.gz
4949
Diffstat (limited to 'subx/055stream.subx')
-rw-r--r--subx/055stream.subx61
1 files changed, 61 insertions, 0 deletions
diff --git a/subx/055stream.subx b/subx/055stream.subx
new file mode 100644
index 00000000..9711c60a
--- /dev/null
+++ b/subx/055stream.subx
@@ -0,0 +1,61 @@
+# streams: data structure for operating on arrays in a stateful manner
+#
+# A stream looks like this:
+#   read : int  # index that we've read until
+#   write : int  # index at which writes go
+#   data : (array byte)  # prefixed by length as usual
+#
+# primitives for operating on streams:
+#   - clear-stream (clears everything but the data length)
+#   - stream-equal? (compares stream data with a string; ignores read pointer)
+#   - rewind-reads (resets read pointer; not yet implemented)
+
+== code
+#   instruction                     effective address                                                   register    displacement    immediate
+# . op          subop               mod             rm32          base        index         scale       r32
+# . 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
+
+# main:
+    e8/call  run-tests/disp32  # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'.
+    # syscall(exit, Num-test-failures)
+    8b/copy                         0/mod/indirect  5/rm32/.disp32            .             .           3/r32/EBX   Num-test-failures/disp32          # copy *Num-test-failures to EBX
+    b8/copy-to-EAX  1/imm32/exit
+    cd/syscall  0x80/imm8
+
+clear-stream:  # f : (address stream) -> <void>
+    # . prolog
+    55/push-EBP
+    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+    # . save registers
+    50/push-EAX
+    51/push-ECX
+    # EAX = f
+    8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .                         0/r32/EAX   8/disp8         .                 # copy *(EBP+8) to EAX
+    # ECX = f->length
+    8b/copy                         1/mod/*+disp8   0/rm32/EAX    .           .             .           1/r32/ECX   8/disp8         .                 # copy *(EAX+8) to ECX
+    # ECX = &f->data[f->length]
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   0xc/disp8       .                 # copy EAX+ECX+12 to ECX
+    # f->write = 0
+    c7          0/subop/copy        0/mod/direct    0/rm32/EAX    .           .             .           .           .               0/imm32           # copy to *EAX
+    # f->read = 0
+    c7          0/subop/copy        1/mod/*+disp8   0/rm32/EAX    .           .             .           .           4/disp8         0/imm32           # copy to *(EAX+4)
+    # EAX = f->data
+    81          0/subop/add         3/mod/direct    0/rm32/EAX    .           .             .           .           .               0xc/imm32         # add to EAX
+    # while (true)
+$clear-stream:loop:
+    # if EAX >= ECX break
+    39/compare                      3/mod/direct    0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # compare EAX with ECX
+    7d/jump-if-greater-or-equal  $clear-stream:end/disp8
+    # *EAX = 0
+    c6          0/subop/copy        0/mod/direct    0/rm32/EAX    .           .             .           .           .               0/imm8            # copy byte to *EAX
+    # ++EAX
+    40/increment-EAX
+    eb/jump  $clear-stream:loop/disp8
+$clear-stream:end:
+    # . restore registers
+    59/pop-to-ECX
+    58/pop-to-EAX
+    # . epilog
+    89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+    5d/pop-to-EBP
+    c3/return