about summary refs log tree commit diff stats
path: root/subx
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2019-05-02 23:44:43 -0700
committerKartik Agaram <vc@akkartik.com>2019-05-02 23:48:52 -0700
commitd134a83b7454911285101dee8d14b9a41671d850 (patch)
tree8a2a01164bf73f001fac05d8979996477c011ebf /subx
parentf2cd405d04cd904bf1ed4d5ddf4916234c0509f5 (diff)
downloadmu-d134a83b7454911285101dee8d14b9a41671d850.tar.gz
new primitives: append-byte, append-byte-hex
These are variants of write-byte-buffered and print-byte-buffered respectively
that operate on in-memory `stream`s rather than `buffered-file`s.

They don't operate on files, so we'll avoid using the prefix 'write-'.
Diffstat (limited to 'subx')
-rw-r--r--subx/064write-byte.subx81
-rw-r--r--subx/066print-byte.subx71
-rw-r--r--subx/Readme.md4
-rwxr-xr-xsubx/apps/assortbin21401 -> 21771 bytes
-rwxr-xr-xsubx/apps/crenshaw2-1bin18589 -> 18959 bytes
-rwxr-xr-xsubx/apps/crenshaw2-1bbin19148 -> 19518 bytes
-rwxr-xr-xsubx/apps/factorialbin17505 -> 17875 bytes
-rwxr-xr-xsubx/apps/handlebin18279 -> 18649 bytes
-rwxr-xr-xsubx/apps/hexbin21598 -> 21968 bytes
-rwxr-xr-xsubx/apps/packbin36190 -> 36560 bytes
10 files changed, 154 insertions, 2 deletions
diff --git a/subx/064write-byte.subx b/subx/064write-byte.subx
index a432171d..606cc7d3 100644
--- a/subx/064write-byte.subx
+++ b/subx/064write-byte.subx
@@ -103,8 +103,6 @@ $flush:end:
     5d/pop-to-EBP
     c3/return
 
-# - tests
-
 test-write-byte-buffered-single:
     # - check that write-byte-buffered writes to first byte of 'file'
     # setup
@@ -208,4 +206,83 @@ test-write-byte-buffered-multiple-flushes:
     # . end
     c3/return
 
+# - variant without buffering
+
+# Write lower byte of 'n' to 'f'.
+append-byte:  # f : (address stream), n : int -> <void>
+    # . prolog
+    55/push-EBP
+    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+    # . save registers
+    51/push-ECX
+    57/push-EDI
+    # EDI = f
+    8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           7/r32/EDI   8/disp8         .                 # copy *(EBP+8) to EDI
+    # ECX = f->write
+    8b/copy                         0/mod/indirect  7/rm32/EDI    .           .             .           1/r32/ECX   .               .                 # copy *EDI to ECX
+    # if (f->write >= f->length) abort
+    3b/compare                      1/mod/*+disp8   7/rm32/EDI    .           .             .           1/r32/ECX   8/disp8         .                 # compare ECX with *(EDI+8)
+    7d/jump-if-greater-or-equal  $append-byte:abort/disp8
+$append-byte:to-stream:
+    # write to stream
+    # f->data[f->write] = LSB(n)
+    31/xor                          3/mod/direct    0/rm32/EAX    .           .             .           0/r32/EAX   .               .                 # clear EAX
+    8a/copy-byte                    1/mod/*+disp8   5/rm32/EBP    .           .             .           0/r32/AL    0xc/disp8       .                 # copy byte at *(EBP+12) to AL
+    88/copy-byte                    1/mod/*+disp8   4/rm32/sib    7/base/EDI  1/index/ECX   .           0/r32/AL    0xc/disp8       .                 # copy AL to *(EDI+ECX+12)
+    # ++f->write
+    ff          0/subop/increment   0/mod/indirect  7/rm32/EDI    .           .             .           .           .               .                 # increment *EDI
+$append-byte:end:
+    # . restore registers
+    5f/pop-to-EDI
+    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
+
+$append-byte:abort:
+    # . _write(2/stderr, error)
+    # . . push args
+    68/push  "append-byte: out of space"/imm32
+    68/push  2/imm32/stderr
+    # . . call
+    e8/call  _write/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # . syscall(exit, 1)
+    bb/copy-to-EBX  1/imm32
+    b8/copy-to-EAX  1/imm32/exit
+    cd/syscall  0x80/imm8
+    # never gets here
+
+test-append-byte-single:
+    # - check that append-byte writes to first byte of 'file'
+    # setup
+    # . clear-stream(_test-stream)
+    # . . push args
+    68/push  _test-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
+    # append-byte(_test-stream, 'A')
+    # . . push args
+    68/push  0x41/imm32
+    68/push  _test-stream/imm32
+    # . . call
+    e8/call  append-byte/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # check-stream-equal(_test-stream, "A", msg)
+    # . . push args
+    68/push  "F - test-append-byte-single"/imm32
+    68/push  "A"/imm32
+    68/push  _test-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
+    # . end
+    c3/return
+
 # . . vim:nowrap:textwidth=0
diff --git a/subx/066print-byte.subx b/subx/066print-byte.subx
index b8b1dd24..80a29a0c 100644
--- a/subx/066print-byte.subx
+++ b/subx/066print-byte.subx
@@ -5,6 +5,77 @@
 # . 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
 
+append-byte-hex:  # f : (address stream), n : int -> <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
+    # AL = convert upper nibble to hex
+    8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           0/r32/EAX   0xc/disp8       .                 # copy *(EBP+12) to EAX
+    c1/shift    5/subop/logic-right 3/mod/direct    0/rm32/EAX    .           .             .           .           .               4/imm8            # shift EAX right by 4 bits, while padding zeroes
+    25/and-EAX  0xf/imm32
+    # . AL = to-hex-char(AL)
+    e8/call  to-hex-char/disp32
+    # append-byte(f, AL)
+    # . . push args
+    50/push-EAX
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           8/disp8         .                 # push *(EBP+8)
+    # . . call
+    e8/call  append-byte/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # AL = convert lower nibble to hex
+    8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           0/r32/EAX   0xc/disp8       .                 # copy *(EBP+12) to EAX
+    25/and-EAX  0xf/imm32
+    # . AL = to-hex-char(AL)
+    e8/call  to-hex-char/disp32
+    # append-byte(f, AL)
+    # . . push args
+    50/push-EAX
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           8/disp8         .                 # push *(EBP+8)
+    # . . call
+    e8/call  append-byte/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+$append-byte-hex:end:
+    # . restore registers
+    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
+
+test-append-byte-hex:
+    # - check that append-byte-hex adds the hex textual representation
+    # setup
+    # . clear-stream(_test-stream)
+    # . . push args
+    68/push  _test-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
+    # append-byte-hex(_test-stream, 0xa)  # exercises digit, non-digit as well as leading zero
+    # . . push args
+    68/push  0xa/imm32
+    68/push  _test-stream/imm32
+    # . . call
+    e8/call  append-byte-hex/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # check-stream-equal(_test-stream, "0a", msg)
+    # . . push args
+    68/push  "F - test-append-byte-hex"/imm32
+    68/push  "0a"/imm32
+    68/push  _test-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
+    # . end
+    c3/return
+
 print-byte-buffered:  # f : (address buffered-file), n : int -> <void>
     # . prolog
     55/push-EBP
diff --git a/subx/Readme.md b/subx/Readme.md
index a27bf0f4..517515d8 100644
--- a/subx/Readme.md
+++ b/subx/Readme.md
@@ -626,6 +626,10 @@ allocated memory for it.)_
 * `write-stream`: stream -> file
   - Can also be used to cat one stream into another.
   - Will abort the entire program if there isn't enough room.
+* `append-byte`: int -> stream
+  - Will abort the entire program if there isn't enough room.
+* `append-byte-hex`: int -> stream
+  - Will abort the entire program if there isn't enough room.
 * `write-buffered`: string -> buffered-file
 * `write-slice-buffered`: slice -> buffered-file
 * `flush`: buffered-file
diff --git a/subx/apps/assort b/subx/apps/assort
index ba20910f..b5961b66 100755
--- a/subx/apps/assort
+++ b/subx/apps/assort
Binary files differdiff --git a/subx/apps/crenshaw2-1 b/subx/apps/crenshaw2-1
index b5614efb..8a927771 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 0a7e2e13..7856904e 100755
--- a/subx/apps/crenshaw2-1b
+++ b/subx/apps/crenshaw2-1b
Binary files differdiff --git a/subx/apps/factorial b/subx/apps/factorial
index dbda72ae..92c70b86 100755
--- a/subx/apps/factorial
+++ b/subx/apps/factorial
Binary files differdiff --git a/subx/apps/handle b/subx/apps/handle
index 650cdd55..b4bf7240 100755
--- a/subx/apps/handle
+++ b/subx/apps/handle
Binary files differdiff --git a/subx/apps/hex b/subx/apps/hex
index 99ac5466..796e532e 100755
--- a/subx/apps/hex
+++ b/subx/apps/hex
Binary files differdiff --git a/subx/apps/pack b/subx/apps/pack
index 318dc3d4..ba40c5a1 100755
--- a/subx/apps/pack
+++ b/subx/apps/pack
Binary files differ