about summary refs log tree commit diff stats
path: root/subx
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2019-07-08 00:42:50 -0700
committerKartik Agaram <vc@akkartik.com>2019-07-08 00:59:35 -0700
commite5cffe30ed38fbbdc74c63d0a94ab2a93713e43d (patch)
treeb719f3cd55c4b1fbfb3515479cf69cd9fb31879d /subx
parentfc07ee4f54b4596f41d47f663ee1370e07cf0847 (diff)
downloadmu-e5cffe30ed38fbbdc74c63d0a94ab2a93713e43d.tar.gz
.
Move test slice variables out of the data segment and close to their
usages. Makes tests a little easier to read even if we spend a few more
instructions each time.
Diffstat (limited to 'subx')
-rw-r--r--subx/065hex.subx193
-rw-r--r--subx/072slice.subx185
-rwxr-xr-xsubx/apps/assortbin28723 -> 29165 bytes
-rwxr-xr-xsubx/apps/crenshaw2-1bin23337 -> 23725 bytes
-rwxr-xr-xsubx/apps/crenshaw2-1bbin23896 -> 24284 bytes
-rwxr-xr-xsubx/apps/dquotesbin35032 -> 35518 bytes
-rw-r--r--subx/apps/dquotes.subx60
-rwxr-xr-xsubx/apps/factorialbin22253 -> 22641 bytes
-rwxr-xr-xsubx/apps/handlebin23112 -> 23500 bytes
-rwxr-xr-xsubx/apps/hexbin26346 -> 26734 bytes
-rwxr-xr-xsubx/apps/packbin43637 -> 44246 bytes
-rw-r--r--subx/apps/pack.subx161
-rw-r--r--subx/apps/subx-common.subx57
-rwxr-xr-xsubx/apps/surveybin34274 -> 34716 bytes
14 files changed, 389 insertions, 267 deletions
diff --git a/subx/065hex.subx b/subx/065hex.subx
index 374168db..d188d4d3 100644
--- a/subx/065hex.subx
+++ b/subx/065hex.subx
@@ -88,9 +88,14 @@ test-is-hex-int:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX = "34"
-    68/push  _test-slice-hex-int-end/imm32
-    68/push  _test-slice-hex-int/imm32
+    # (EAX..ECX) = "34"
+    b8/copy-to-EAX  "34"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = is-hex-int?(slice)
     # . . push args
@@ -117,9 +122,14 @@ test-is-hex-int-handles-letters:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX = "34a"
-    68/push  _test-slice-hex-int-letters-end/imm32
-    68/push  _test-slice-hex-int-letters/imm32
+    # (EAX..ECX) = "34a"
+    b8/copy-to-EAX  "34a"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = is-hex-int?(slice)
     # . . push args
@@ -146,9 +156,14 @@ test-is-hex-int-with-trailing-char:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX = "34q"
-    68/push  _test-slice-digits-and-char-end/imm32
-    68/push  _test-slice-digits-and-char/imm32
+    # (EAX..ECX) = "34q"
+    b8/copy-to-EAX  "34q"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = is-hex-int?(slice)
     # . . push args
@@ -175,9 +190,14 @@ test-is-hex-int-with-leading-char:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX = "q34"
-    68/push  _test-slice-char-and-digits-end/imm32
-    68/push  _test-slice-char-and-digits/imm32
+    # (EAX..ECX) = "q34"
+    b8/copy-to-EAX  "q34"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = is-hex-int?(slice)
     # . . push args
@@ -205,8 +225,8 @@ test-is-hex-int-empty:
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
     # var slice/ECX = ""
-    68/push  _test-slice-empty-end/imm32
-    68/push  _test-slice-empty/imm32
+    68/push  0/imm32
+    68/push  0/imm32
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = is-hex-int?(slice)
     # . . push args
@@ -233,9 +253,14 @@ test-is-hex-int-handles-0x-prefix:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX = "0x3a"
-    68/push  _test-slice-hex-int-with-0x-prefix-end/imm32
-    68/push  _test-slice-hex-int-with-0x-prefix/imm32
+    # (EAX..ECX) = "0x3a"
+    b8/copy-to-EAX  "0x3a"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = is-hex-int?(slice)
     # . . push args
@@ -262,9 +287,14 @@ test-is-hex-int-handles-negative:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX = "-34a"
-    68/push  _test-slice-hex-int-letters-end/imm32
-    68/push  _test-slice-hex-int-letters-negative/imm32
+    # (EAX..ECX) = "-34a"
+    b8/copy-to-EAX  "-34a"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = is-hex-int?(slice)
     # . . push args
@@ -291,9 +321,14 @@ test-is-hex-int-handles-negative-0x-prefix:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX = "-0x3a"
-    68/push  _test-slice-hex-int-with-0x-prefix-end/imm32
-    68/push  _test-slice-hex-int-with-0x-prefix-negative/imm32
+    # (EAX..ECX) = "-0x3a"
+    b8/copy-to-EAX  "-0x3a"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = is-hex-int?(slice)
     # . . push args
@@ -400,9 +435,14 @@ test-parse-hex-int-single-digit:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX = "a"
-    68/push  _test-slice-hex-int-single-letter-end/imm32
-    68/push  _test-slice-hex-int-single-letter/imm32
+    # (EAX..ECX) = "a"
+    b8/copy-to-EAX  "a"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = parse-hex-int(slice)
     # . . push args
@@ -429,9 +469,14 @@ test-parse-hex-int-multi-digit:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX = "34a"
-    68/push  _test-slice-hex-int-letters-end/imm32
-    68/push  _test-slice-hex-int-letters/imm32
+    # (EAX..ECX) = "34a"
+    b8/copy-to-EAX  "34a"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = parse-hex-int(slice)
     # . . push args
@@ -458,9 +503,14 @@ test-parse-hex-int-0x-prefix:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX = "0x34"
-    68/push  _test-slice-hex-int-with-0x-prefix-end/imm32
-    68/push  _test-slice-hex-int-with-0x-prefix/imm32
+    # (EAX..ECX) = "0x34"
+    b8/copy-to-EAX  "0x34"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = parse-hex-int(slice)
     # . . push args
@@ -487,9 +537,14 @@ test-parse-hex-int-zero:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX = "0"
-    68/push  _test-slice-hex-int-zero-end/imm32
-    68/push  _test-slice-hex-int-zero/imm32
+    # (EAX..ECX) = "0"
+    b8/copy-to-EAX  "0"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = parse-hex-int(slice)
     # . . push args
@@ -516,9 +571,14 @@ test-parse-hex-int-0-prefix:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX = "03"
-    68/push  _test-slice-hex-int-with-0-prefix-end/imm32
-    68/push  _test-slice-hex-int-with-0-prefix/imm32
+    # (EAX..ECX) = "03"
+    b8/copy-to-EAX  "03"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = parse-hex-int(slice)
     # . . push args
@@ -545,9 +605,14 @@ test-parse-hex-int-negative:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX = "-03"
-    68/push  _test-slice-hex-int-negative-with-0-prefix-end/imm32
-    68/push  _test-slice-hex-int-negative-with-0-prefix/imm32
+    # (EAX..ECX) = "-03"
+    b8/copy-to-EAX  "-03"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = parse-hex-int(slice)
     # . . push args
@@ -753,50 +818,4 @@ $to-hex-char:else:
     05/add-to-EAX  0x57/imm32/a-10
     c3/return
 
-== data
-
-_test-slice-empty:
-  # nothing
-_test-slice-empty-end:
-
-_test-slice-hex-int:
-  33/3 34/4
-_test-slice-hex-int-end:
-
-_test-slice-hex-int-letters-negative:
-  2d/-
-_test-slice-hex-int-letters:
-  33/3 34/4 61/a
-_test-slice-hex-int-letters-end:
-
-_test-slice-hex-int-single-letter:
-  61/a
-_test-slice-hex-int-single-letter-end:
-
-_test-slice-char-and-digits:
-  71/q 33/3 34/4
-_test-slice-char-and-digits-end:
-
-_test-slice-digits-and-char:
-  33/3 34/4 71/q
-_test-slice-digits-and-char-end:
-
-_test-slice-hex-int-with-0x-prefix-negative:
-  2d/-
-_test-slice-hex-int-with-0x-prefix:
-  30/0 78/x 33/3 34/4
-_test-slice-hex-int-with-0x-prefix-end:
-
-_test-slice-hex-int-zero:
-  30/0
-_test-slice-hex-int-zero-end:
-
-_test-slice-hex-int-with-0-prefix:
-  30/0 33/3
-_test-slice-hex-int-with-0-prefix-end:
-
-_test-slice-hex-int-negative-with-0-prefix:
-  2d/- 30/0 33/3
-_test-slice-hex-int-negative-with-0-prefix-end:
-
 # . . vim:nowrap:textwidth=0
diff --git a/subx/072slice.subx b/subx/072slice.subx
index c9a7fe4a..e568fbae 100644
--- a/subx/072slice.subx
+++ b/subx/072slice.subx
@@ -181,9 +181,14 @@ test-slice-equal:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX
-    68/push  _test-slice-data-3/imm32/end
-    68/push  _test-slice-data-0/imm32/start
+    # (EAX..ECX) = "Abc"
+    b8/copy-to-EAX  "Abc"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = slice-equal?(ECX, "Abc")
     # . . push args
@@ -212,9 +217,14 @@ test-slice-equal-false:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX
-    68/push  _test-slice-data-4/imm32/end
-    68/push  _test-slice-data-1/imm32/start
+    # (EAX..ECX) = "bcd"
+    b8/copy-to-EAX  "bcd"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = slice-equal?(ECX, "Abc")
     # . . push args
@@ -243,9 +253,14 @@ test-slice-equal-too-long:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX
-    68/push  _test-slice-data-4/imm32/end
-    68/push  _test-slice-data-0/imm32/start
+    # (EAX..ECX) = "Abcd"
+    b8/copy-to-EAX  "Abcd"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = slice-equal?(ECX, "Abc")
     # . . push args
@@ -274,9 +289,14 @@ test-slice-equal-too-short:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX
-    68/push  _test-slice-data-1/imm32/end
-    68/push  _test-slice-data-0/imm32/start
+    # (EAX..ECX) = "A"
+    b8/copy-to-EAX  "A"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = slice-equal?(ECX, "Abc")
     # . . push args
@@ -306,8 +326,8 @@ test-slice-equal-empty:
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
     # var slice/ECX
-    68/push  _test-slice-data-0/imm32/end
-    68/push  _test-slice-data-0/imm32/start
+    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
     # EAX = slice-equal?(ECX, "Abc")
     # . . push args
@@ -336,9 +356,14 @@ test-slice-equal-with-empty:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX
-    68/push  _test-slice-data-2/imm32/end
-    68/push  _test-slice-data-0/imm32/start
+    # (EAX..ECX) = "Ab"
+    b8/copy-to-EAX  "Ab"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = slice-equal?(ECX, "")
     # . . push args
@@ -368,8 +393,8 @@ test-slice-equal-empty-with-empty:
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
     # var slice/ECX
-    68/push  _test-slice-data-0/imm32/end
-    68/push  _test-slice-data-0/imm32/start
+    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
     # EAX = slice-equal?(ECX, "")
     # . . push args
@@ -398,9 +423,14 @@ test-slice-equal-with-null:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX
-    68/push  _test-slice-data-2/imm32/end
-    68/push  _test-slice-data-0/imm32/start
+    # (EAX..ECX) = "Ab"
+    b8/copy-to-EAX  "Ab"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = slice-equal?(ECX, 0)
     # . . push args
@@ -516,9 +546,14 @@ test-slice-starts-with-single-character:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX
-    68/push  _test-slice-data-3/imm32/end
-    68/push  _test-slice-data-0/imm32/start
+    # (EAX..ECX) = "Abc"
+    b8/copy-to-EAX  "Abc"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = slice-starts-with?(ECX, "A")
     # . . push args
@@ -547,9 +582,14 @@ test-slice-starts-with-empty-string:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX
-    68/push  _test-slice-data-3/imm32/end
-    68/push  _test-slice-data-0/imm32/start
+    # (EAX..ECX) = "Abc"
+    b8/copy-to-EAX  "Abc"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = slice-starts-with?(ECX, "")
     # . . push args
@@ -578,9 +618,14 @@ test-slice-starts-with-multiple-characters:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX
-    68/push  _test-slice-data-3/imm32/end
-    68/push  _test-slice-data-0/imm32/start
+    # (EAX..ECX) = "Abc"
+    b8/copy-to-EAX  "Abc"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = slice-starts-with?(ECX, "Ab")
     # . . push args
@@ -609,9 +654,14 @@ test-slice-starts-with-entire-string:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX
-    68/push  _test-slice-data-3/imm32/end
-    68/push  _test-slice-data-0/imm32/start
+    # (EAX..ECX) = "Abc"
+    b8/copy-to-EAX  "Abc"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = slice-starts-with?(ECX, "Abc")
     # . . push args
@@ -640,9 +690,14 @@ test-slice-starts-with-fails:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX
-    68/push  _test-slice-data-3/imm32/end
-    68/push  _test-slice-data-0/imm32/start
+    # (EAX..ECX) = "Abc"
+    b8/copy-to-EAX  "Abc"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = slice-starts-with?(ECX, "Abd")
     # . . push args
@@ -671,9 +726,14 @@ test-slice-starts-with-fails-2:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX
-    68/push  _test-slice-data-3/imm32/end
-    68/push  _test-slice-data-0/imm32/start
+    # (EAX..ECX) = "Abc"
+    b8/copy-to-EAX  "Abc"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = slice-starts-with?(ECX, "Ac")
     # . . push args
@@ -783,9 +843,14 @@ test-write-slice:
     e8/call  clear-stream/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-    # var slice/ECX = "Abc"
-    68/push  _test-slice-data-3/imm32/end
-    68/push  _test-slice-data-0/imm32/start
+    # (EAX..ECX) = "Abc"
+    b8/copy-to-EAX  "Abc"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # write-slice(_test-stream, slice)
     # . . push args
@@ -908,9 +973,14 @@ test-write-slice-buffered:
     e8/call  clear-stream/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-    # var slice/ECX = "Abc"
-    68/push  _test-slice-data-3/imm32/end
-    68/push  _test-slice-data-0/imm32/start
+    # (EAX..ECX) = "Abc"
+    b8/copy-to-EAX  "Abc"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # write-slice-buffered(_test-buffered-file, slice)
     # . . push args
@@ -1035,9 +1105,14 @@ test-slice-to-string:
     e8/call  new-segment/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-    # var slice/ECX = "Abc"
-    68/push  _test-slice-data-3/imm32/end
-    68/push  _test-slice-data-0/imm32/start
+    # (EAX..ECX) = "Abc"
+    b8/copy-to-EAX  "Abc"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = slice-to-string(heap, slice)
     # . . push args
@@ -1095,16 +1170,4 @@ test-slice-to-string:
     5d/pop-to-EBP
     c3/return
 
-== data
-
-_test-slice-data-0:
-    41/A
-_test-slice-data-1:
-    62/b
-_test-slice-data-2:
-    63/c
-_test-slice-data-3:
-    64/d
-_test-slice-data-4:
-
 # . . vim:nowrap:textwidth=0
diff --git a/subx/apps/assort b/subx/apps/assort
index 10573301..7407a4f0 100755
--- a/subx/apps/assort
+++ b/subx/apps/assort
Binary files differdiff --git a/subx/apps/crenshaw2-1 b/subx/apps/crenshaw2-1
index f25d054c..2dc6e6d4 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 720eef0d..efa0ece7 100755
--- a/subx/apps/crenshaw2-1b
+++ b/subx/apps/crenshaw2-1b
Binary files differdiff --git a/subx/apps/dquotes b/subx/apps/dquotes
index 6015a4c6..30751dd4 100755
--- a/subx/apps/dquotes
+++ b/subx/apps/dquotes
Binary files differdiff --git a/subx/apps/dquotes.subx b/subx/apps/dquotes.subx
index 64742599..d4a1ae86 100644
--- a/subx/apps/dquotes.subx
+++ b/subx/apps/dquotes.subx
@@ -1032,7 +1032,7 @@ test-emit-string-literal-data:
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
     # var slice/ECX = '"abc"/d'
-    68/push  _test-slice-abc-metadata-end/imm32
+    68/push  _test-slice-abc-end/imm32
     68/push  _test-slice-abc/imm32
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # emit-string-literal-data(_test-output-stream, slice)
@@ -1096,8 +1096,8 @@ test-emit-string-literal-data-empty:
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
     # var slice/ECX = '""'
-    68/push  _test-slice-empty-string-literal-end/imm32
-    68/push  _test-slice-empty-string-literal/imm32
+    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
     # emit-string-literal-data(_test-output-stream, slice)
     # . . push args
@@ -1389,9 +1389,14 @@ test-emit-metadata:
     e8/call  clear-stream/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-    # var slice/ECX = "abc/def"
-    68/push  _test-slice-word-end/imm32
-    68/push  _test-slice-word/imm32/start
+    # (EAX..ECX) = "abc/def"
+    b8/copy-to-EAX  "abc/def"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # emit-metadata(_test-output-buffered-file, slice)
     # . . push args
@@ -1443,9 +1448,14 @@ test-emit-metadata-none:
     e8/call  clear-stream/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-    # var slice/ECX = "abc"
-    68/push  _test-slice-word-datum-end/imm32
-    68/push  _test-slice-word/imm32/start
+    # (EAX..ECX) = "abc"
+    b8/copy-to-EAX  "abc"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # emit-metadata(_test-output-buffered-file, slice)
     # . . push args
@@ -1497,9 +1507,14 @@ test-emit-metadata-multiple:
     e8/call  clear-stream/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-    # var slice/ECX = "abc/def/ghi"
-    68/push  _test-slice-word-end2/imm32
-    68/push  _test-slice-word/imm32/start
+    # (EAX..ECX) = "abc/def/ghi"
+    b8/copy-to-EAX  "abc/def/ghi"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # emit-metadata(_test-output-buffered-file, slice)
     # . . push args
@@ -1613,7 +1628,7 @@ test-emit-metadata-in-string-literal:
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
     # var slice/ECX = "\"abc/def\"/ghi"
-    68/push  _test-slice-literal-string-with-metadata-end/imm32
+    68/push  _test-slice-literal-string-with-end/imm32
     68/push  _test-slice-literal-string/imm32/start
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # emit-metadata(_test-output-buffered-file, slice)
@@ -2645,13 +2660,8 @@ Slash:
 
 _test-slice-abc:
   22/dquote 61/a 62/b 63/c 22/dquote  # "abc"
-_test-slice-abc-end:
   2f/slash 64/d
-_test-slice-abc-metadata-end:
-
-_test-slice-empty-string-literal:
-  22/dquote 22/dquote  # ""
-_test-slice-empty-string-literal-end:
+_test-slice-abc-end:
 
 _test-slice-a-space-b:
   22/dquote 61/a 20/space 62/b 22/dquote  # "a b"
@@ -2661,23 +2671,13 @@ _test-slice-a-dquote-b:
   22/dquote 61/a 5c/backslash 22/dquote 62/b 22/dquote  # "a\"b"
 _test-slice-a-dquote-b-end:
 
-# abc/def/ghi
-_test-slice-word:
-  61/a 62/b 63/c  # abc
-_test-slice-word-datum-end:
-  2f/slash 64/d 65/e 66/f  # /def
-_test-slice-word-end:
-  2f/slash 67/g 68/h 69/i  # /ghi
-_test-slice-word-end2:
-
 # "abc/def"/ghi
 _test-slice-literal-string:
   22/dquote
   61/a 62/b 63/c  # abc
   2f/slash 64/d 65/e 66/f  # /def
   22/dquote
-_test-slice-literal-string-end:
   2f/slash 67/g 68/h 69/i  # /ghi
-_test-slice-literal-string-with-metadata-end:
+_test-slice-literal-string-with-end:
 
 # . . vim:nowrap:textwidth=0
diff --git a/subx/apps/factorial b/subx/apps/factorial
index dc637731..2433b2a6 100755
--- a/subx/apps/factorial
+++ b/subx/apps/factorial
Binary files differdiff --git a/subx/apps/handle b/subx/apps/handle
index 16041394..d1cbb74b 100755
--- a/subx/apps/handle
+++ b/subx/apps/handle
Binary files differdiff --git a/subx/apps/hex b/subx/apps/hex
index db95f583..5bfa5863 100755
--- a/subx/apps/hex
+++ b/subx/apps/hex
Binary files differdiff --git a/subx/apps/pack b/subx/apps/pack
index 73e680b7..78018753 100755
--- a/subx/apps/pack
+++ b/subx/apps/pack
Binary files differdiff --git a/subx/apps/pack.subx b/subx/apps/pack.subx
index 1e6c1fbc..7c12115a 100644
--- a/subx/apps/pack.subx
+++ b/subx/apps/pack.subx
@@ -5948,9 +5948,14 @@ test-emit-number:
     e8/call  clear-stream/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-    # var slice/ECX = "30"
-    68/push  _test-slice-three-zero-end/imm32/end
-    68/push  _test-slice-three-zero/imm32/start
+    # (EAX..ECX) = "30"
+    b8/copy-to-EAX  "30"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # emit(_test-output-buffered-file, slice, 1)
     # . . push args
@@ -6004,9 +6009,14 @@ test-emit-negative-number:
     e8/call  clear-stream/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-    # var slice/ECX = "-2"
-    68/push  _test-slice-negative-two-end/imm32/end
-    68/push  _test-slice-negative-two/imm32/start
+    # (EAX..ECX) = "-2"
+    b8/copy-to-EAX  "-2"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # emit(_test-output-buffered-file, slice, 2)
     # . . push args
@@ -6059,9 +6069,14 @@ test-emit-number-with-metadata:
     e8/call  clear-stream/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-    # var slice/ECX = "-2/foo"
-    68/push  _test-slice-negative-two-metadata-end/imm32/end
-    68/push  _test-slice-negative-two/imm32/start
+    # (EAX..ECX) = "-2/foo"
+    b8/copy-to-EAX  "-2/foo"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # emit(_test-output-buffered-file, slice, 2)
     # . . push args
@@ -6115,9 +6130,14 @@ test-emit-non-number:
     e8/call  clear-stream/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-    # var slice/ECX = "xyz"
-    68/push  _test-slice-non-number-word-end/imm32/end
-    68/push  _test-slice-non-number-word/imm32/start
+    # (EAX..ECX) = "xyz"
+    b8/copy-to-EAX  "xyz"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # emit(_test-output-buffered-file, slice, 2)
     # . . push args
@@ -6170,9 +6190,14 @@ test-emit-non-number-with-metadata:
     e8/call  clear-stream/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-    # var slice/ECX = "xyz/"
-    68/push  _test-slice-non-number-word-metadata-end/imm32/end
-    68/push  _test-slice-non-number-word/imm32/start
+    # (EAX..ECX) = "xyz/"
+    b8/copy-to-EAX  "xyz/"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # emit(_test-output-buffered-file, slice, 2)
     # . . push args
@@ -6225,9 +6250,14 @@ test-emit-non-number-with-all-hex-digits-and-metadata:
     e8/call  clear-stream/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-    # var slice/ECX = "abcd/xyz"
-    68/push  _test-slice-hexlike-non-number-word-metadata-end/imm32/end
-    68/push  _test-slice-hexlike-non-number-word/imm32/start
+    # (EAX..ECX) = "abcd/xyz"
+    b8/copy-to-EAX  "abcd/xyz"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # emit(_test-output-buffered-file, slice, 2)
     # . . push args
@@ -6351,9 +6381,14 @@ test-is-valid-name-digit-prefix:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX = "34"
-    68/push  _test-slice-hex-int-end/imm32
-    68/push  _test-slice-hex-int/imm32
+    # (EAX..ECX) = "34"
+    b8/copy-to-EAX  "34"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = is-valid-name?(slice)
     # . . push args
@@ -6380,9 +6415,14 @@ test-is-valid-name-negative-prefix:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX = "-0x34"
-    68/push  _test-slice-hex-int-with-0x-prefix-end/imm32
-    68/push  _test-slice-hex-int-with-0x-prefix-negative/imm32
+    # (EAX..ECX) = "-0x34"
+    b8/copy-to-EAX  "-0x34"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = is-valid-name?(slice)
     # . . push args
@@ -6409,9 +6449,14 @@ test-is-valid-name-0x-prefix:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX = "0x34"
-    68/push  _test-slice-hex-int-with-0x-prefix-end/imm32
-    68/push  _test-slice-hex-int-with-0x-prefix/imm32
+    # (EAX..ECX) = "0x34"
+    b8/copy-to-EAX  "0x34"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = is-valid-name?(slice)
     # . . push args
@@ -6438,9 +6483,14 @@ test-is-valid-name-starts-with-pre-digit:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX = "/03"
-    68/push  _test-slice-with-slash-prefix-end/imm32
-    68/push  _test-slice-with-slash-prefix/imm32
+    # (EAX..ECX) = "/03"
+    b8/copy-to-EAX  "/03"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = is-valid-name?(slice)
     # . . push args
@@ -6467,9 +6517,14 @@ test-is-valid-name-starts-with-post-digit:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX = "q34"
-    68/push  _test-slice-char-and-digits-end/imm32
-    68/push  _test-slice-char-and-digits/imm32
+    # (EAX..ECX) = "q34"
+    b8/copy-to-EAX  "q34"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = is-valid-name?(slice)
     # . . push args
@@ -6496,9 +6551,14 @@ test-is-valid-name-starts-with-digit:
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var slice/ECX = "0x34"
-    68/push  _test-slice-hex-int-with-0x-prefix-end/imm32
-    68/push  _test-slice-hex-int-with-0x-prefix/imm32
+    # (EAX..ECX) = "0x34"
+    b8/copy-to-EAX  "0x34"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # EAX = is-valid-name?(slice)
     # . . push args
@@ -6806,33 +6866,4 @@ $parse-datum-of-word:end:
     5d/pop-to-EBP
     c3/return
 
-== data
-
-_test-slice-negative-two:
-    2d/- 32/2
-_test-slice-negative-two-end:
-    2f/slash 66/f 6f/o 6f/o
-_test-slice-negative-two-metadata-end:
-
-_test-slice-three-zero:
-    33/3 30/0
-_test-slice-three-zero-end:
-
-_test-slice-non-number-word:
-    78/x 79/y 7a/z
-_test-slice-non-number-word-end:
-    2f/slash
-_test-slice-non-number-word-metadata-end:
-
-_test-slice-hexlike-non-number-word:
-    61/a 62/b 63/c 64/d
-_test-slice-hexlike-non-number-word-end:
-    2f/slash
-    78/x 79/y 7a/z
-_test-slice-hexlike-non-number-word-metadata-end:
-
-_test-slice-with-slash-prefix:
-  2f/slash 30/0 33/3
-_test-slice-with-slash-prefix-end:
-
 # . . vim:nowrap:textwidth=0
diff --git a/subx/apps/subx-common.subx b/subx/apps/subx-common.subx
index d71cd373..d2eba587 100644
--- a/subx/apps/subx-common.subx
+++ b/subx/apps/subx-common.subx
@@ -373,9 +373,14 @@ test-get-or-insert-slice:
     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
-    # EDX : (address slice) = "code"
-    68/push  _test-code-segment-end/imm32/end
-    68/push  _test-code-segment/imm32/start
+    # (EAX..EDX) = "code"
+    b8/copy-to-EAX  "code"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           2/r32/EDX   .               .                 # copy *EAX to EDX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  2/index/EDX   .           2/r32/EDX   4/disp8         .                 # copy EAX+EDX+4 to EDX
+    05/add-to-EAX  4/imm32
+    # var slice/EDX = {EAX, EDX}
+    52/push-EDX
+    50/push-EAX
     89/copy                         3/mod/direct    2/rm32/EDX    .           .             .           4/r32/ESP   .               .                 # copy ESP to EDX
 $test-get-or-insert-slice:first-call:
     # - start with an empty table, insert one key, verify that it was inserted
@@ -461,9 +466,15 @@ $test-get-or-insert-slice:second-call:
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
 $test-get-or-insert-slice:third-call:
     # - insert a new key, verify that it was inserted
-    # EDX : (address slice) = "data"
-    c7          0/subop/copy        0/mod/indirect  2/rm32/EDX    .           .             .           .           .               _test-data-segment/imm32  # copy to *EDX
-    c7          0/subop/copy        1/mod/*+disp8   2/rm32/EDX    .           .             .           .           4/disp8         _test-data-segment-end/imm32  # copy to *(EDX+4)
+    # (EAX..EDX) = "data"
+    b8/copy-to-EAX  "data"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           2/r32/EDX   .               .                 # copy *EAX to EDX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  2/index/EDX   .           2/r32/EDX   4/disp8         .                 # copy EAX+EDX+4 to EDX
+    05/add-to-EAX  4/imm32
+    # var slice/EDX = {EAX, EDX}
+    52/push-EDX
+    50/push-EAX
+    89/copy                         3/mod/direct    2/rm32/EDX    .           .             .           4/r32/ESP   .               .                 # copy ESP to EDX
     # EAX = get-or-insert-slice(table, "data" slice, 8 bytes per row)
     # . . push args
     68/push  8/imm32/row-size
@@ -1373,9 +1384,14 @@ test-is-label?:
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
 $test-is-label?:true:
-    # var slice/ECX = slice("AAA:")
-    68/push  _test-label-slice-end1/imm32
-    68/push  _test-label-slice-start/imm32
+    # (EAX..ECX) = "AAA:"
+    b8/copy-to-EAX  "AAA:"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # is-label?(slice/ECX)
     51/push-ECX
@@ -1392,9 +1408,14 @@ $test-is-label?:true:
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
 $test-is-label?:false:
-    # var slice/ECX = slice("AAA")
-    68/push  _test-label-slice-end2/imm32
-    68/push  _test-label-slice-start/imm32
+    # (EAX..ECX) = "AAA"
+    b8/copy-to-EAX  "AAA"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
+    05/add-to-EAX  4/imm32
+    # var slice/ECX = {EAX, ECX}
+    51/push-ECX
+    50/push-EAX
     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
     # is-label?(slice/ECX)
     51/push-ECX
@@ -1493,20 +1514,8 @@ _test-output-buffered-file:
     # data
     00 00 00 00 00 00  # 6 bytes
 
-_test-code-segment:
-  63/c 6f/o 64/d 65/e
-_test-code-segment-end:
-
 _test-data-segment:
   64/d 61/a 74/t 61/a
 _test-data-segment-end:
 
-_test-label-slice-start:
-  41/A
-  41/A
-  41/A
-_test-label-slice-end2:
-  3A/:
-_test-label-slice-end1:
-
 # . . vim:nowrap:textwidth=0
diff --git a/subx/apps/survey b/subx/apps/survey
index 9979e237..00124c44 100755
--- a/subx/apps/survey
+++ b/subx/apps/survey
Binary files differ