about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2018-10-05 21:30:22 -0700
committerKartik Agaram <vc@akkartik.com>2018-10-05 21:30:22 -0700
commit94ad882e828f83df4a4cc0deab1a10e9d5e54eec (patch)
treef51448732674fa8744e8517c4755255afc764b1f
parent03d50cc83c7c2bebb2b019667b80c1c51f4a8def (diff)
downloadmu-94ad882e828f83df4a4cc0deab1a10e9d5e54eec.tar.gz
4668
-rw-r--r--subx/030---operands.cc32
-rw-r--r--subx/031check_operands.cc5
-rw-r--r--subx/034compute_segment_address.cc6
-rw-r--r--subx/035labels.cc41
-rw-r--r--subx/036global_variables.cc6
-rw-r--r--subx/038---literal_strings.cc2
-rw-r--r--subx/050write_stderr.subx4
-rw-r--r--subx/052kernel_string_equal.subx14
-rw-r--r--subx/053new_segment.subx8
-rw-r--r--subx/054string_equal.subx8
-rw-r--r--subx/apps/crenshaw2-1.subx12
-rw-r--r--subx/apps/factorial.subx4
-rw-r--r--subx/examples/ex1.subx4
-rw-r--r--subx/examples/ex10.subx10
-rw-r--r--subx/examples/ex11.subx18
-rw-r--r--subx/examples/ex12.subx6
-rw-r--r--subx/examples/ex2.subx4
-rw-r--r--subx/examples/ex3.subx6
-rw-r--r--subx/examples/ex4.subx18
-rw-r--r--subx/examples/ex5.subx14
-rw-r--r--subx/examples/ex6.subx8
-rw-r--r--subx/examples/ex7.subx58
-rw-r--r--subx/examples/ex8.subx4
-rw-r--r--subx/examples/ex9.subx2
24 files changed, 132 insertions, 162 deletions
diff --git a/subx/030---operands.cc b/subx/030---operands.cc
index 34953480..196e8556 100644
--- a/subx/030---operands.cc
+++ b/subx/030---operands.cc
@@ -29,10 +29,7 @@ cerr << "  instructions\n";
 
 :(scenario pack_immediate_constants)
 == 0x1
-# instruction                     effective address                                                   operand     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
-  bb                                                                                                                              0x2a/imm32        # copy 42 to EBX
+bb  0x2a/imm32
 +transform: packing instruction 'bb 0x2a/imm32'
 +transform: instruction after packing: 'bb 2a 00 00 00'
 +run: copy imm32 0x0000002a to EBX
@@ -335,40 +332,31 @@ void transform(const string& text_bytes) {
 
 :(scenario pack_imm32_large)
 == 0x1
-b9 0x080490a7/imm32  # copy to ECX
+b9  0x080490a7/imm32
 +transform: packing instruction 'b9 0x080490a7/imm32'
 +transform: instruction after packing: 'b9 a7 90 04 08'
 
 :(scenario pack_immediate_constants_hex)
 == 0x1
-# instruction                     effective address                                                   operand     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
-  bb                                                                                                                              0x2a/imm32        # copy 42 to EBX
-+transform: packing instruction 'bb 0x2a/imm32'
-+transform: instruction after packing: 'bb 2a 00 00 00'
-+run: copy imm32 0x0000002a to EBX
+b9  0x2a/imm32
++transform: packing instruction 'b9 0x2a/imm32'
++transform: instruction after packing: 'b9 2a 00 00 00'
++run: copy imm32 0x0000002a to ECX
 
 :(scenarios transform)
 :(scenario pack_silently_ignores_non_hex)
 % Hide_errors = true;
 == 0x1
-# instruction                     effective address                                                   operand     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
-  bb                                                                                                                              foo/imm32         # copy to EBX
-+transform: packing instruction 'bb foo/imm32'
+b9  foo/imm32
++transform: packing instruction 'b9 foo/imm32'
 # no change (we're just not printing metadata to the trace)
-+transform: instruction after packing: 'bb foo'
++transform: instruction after packing: 'b9 foo'
 :(scenarios run)
 
 :(scenario pack_flags_bad_hex)
 % Hide_errors = true;
 == 0x1
-# instruction                     effective address                                                   operand     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
-  bb                                                                                                                              0xfoo/imm32       # copy to EBX
+b9  0xfoo/imm32
 +error: not a number: 0xfoo
 
 //:: helpers
diff --git a/subx/031check_operands.cc b/subx/031check_operands.cc
index f24eb62c..04dac5ba 100644
--- a/subx/031check_operands.cc
+++ b/subx/031check_operands.cc
@@ -4,10 +4,7 @@
 :(scenario check_missing_imm8_operand)
 % Hide_errors = true;
 == 0x1
-# instruction                     effective address                                                   operand     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
-  cd                                                                                                                                                # int ??
+cd  # int ??
 +error: 'cd' (software interrupt): missing imm8 operand
 
 :(before "Pack Operands(segment code)")
diff --git a/subx/034compute_segment_address.cc b/subx/034compute_segment_address.cc
index 28aab137..f6513114 100644
--- a/subx/034compute_segment_address.cc
+++ b/subx/034compute_segment_address.cc
@@ -4,7 +4,7 @@
 
 :(scenario segment_name)
 == code
-05/add 0x0d0c0b0a/imm32  # add 0x0d0c0b0a to EAX
+05/add-to-EAX  0x0d0c0b0a/imm32
 # code starts at 0x08048000 + p_offset, which is 0x54 for a single-segment binary
 +load: 0x09000054 -> 05
 +load: 0x09000055 -> 0a
@@ -65,9 +65,9 @@ if (Currently_parsing_named_segment) {
 
 :(scenario repeated_segment_merges_data)
 == code
-05/add 0x0d0c0b0a/imm32  # add 0x0d0c0b0a to EAX
+05/add-to-EAX  0x0d0c0b0a/imm32
 == code
-2d/subtract 0xddccbbaa/imm32  # subtract 0xddccbbaa from EAX
+2d/subtract-from-EAX  0xddccbbaa/imm32
 +parse: new segment 'code'
 +parse: prepending to segment 'code'
 +load: 0x09000054 -> 2d
diff --git a/subx/035labels.cc b/subx/035labels.cc
index 6461f88e..e2f07d2b 100644
--- a/subx/035labels.cc
+++ b/subx/035labels.cc
@@ -26,7 +26,7 @@ if (SIZE(s) == 2) return true;
 :(scenario pack_immediate_ignores_single_byte_nondigit_operand)
 % Hide_errors = true;
 == 0x1
-b9/copy a/imm32  # copy to ECX
+b9/copy  a/imm32
 +transform: packing instruction 'b9/copy a/imm32'
 # no change (we're just not printing metadata to the trace)
 +transform: instruction after packing: 'b9 a'
@@ -34,7 +34,7 @@ b9/copy a/imm32  # copy to ECX
 :(scenario pack_immediate_ignores_3_hex_digit_operand)
 % Hide_errors = true;
 == 0x1
-b9/copy aaa/imm32  # copy to ECX
+b9/copy  aaa/imm32
 +transform: packing instruction 'b9/copy aaa/imm32'
 # no change (we're just not printing metadata to the trace)
 +transform: instruction after packing: 'b9 aaa'
@@ -42,7 +42,7 @@ b9/copy aaa/imm32  # copy to ECX
 :(scenario pack_immediate_ignores_non_hex_operand)
 % Hide_errors = true;
 == 0x1
-b9/copy xxx/imm32  # copy to ECX
+b9/copy xxx/imm32
 +transform: packing instruction 'b9/copy xxx/imm32'
 # no change (we're just not printing metadata to the trace)
 +transform: instruction after packing: 'b9 xxx'
@@ -70,11 +70,8 @@ void check_valid_name(const string& s) {
 
 :(scenario map_label)
 == 0x1
-          # instruction                     effective address                                                   operand     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
 loop:
-            05                                                                                                                              0x0d0c0b0a/imm32  # add to EAX
+  05  0x0d0c0b0a/imm32
 +transform: label 'loop' is at address 1
 
 :(before "End Level-2 Transforms")
@@ -207,18 +204,15 @@ string drop_last(const string& s) {
 
 :(scenario multiple_labels_at)
 == 0x1
-          # instruction                     effective address                                                   operand     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
 # address 1
 loop:
  $loop2:
 # address 1 (labels take up no space)
-            05                                                                                                                              0x0d0c0b0a/imm32  # add to EAX
+    05  0x0d0c0b0a/imm32
 # address 6
-            eb                                                                                                              $loop2/disp8
+    eb  $loop2/disp8
 # address 8
-            eb                                                                                                              $loop3/disp8
+    eb  $loop3/disp8
 # address 0xa
  $loop3:
 +transform: label 'loop' is at address 1
@@ -232,31 +226,22 @@ loop:
 :(scenario label_too_short)
 % Hide_errors = true;
 == 0x1
-          # instruction                     effective address                                                   operand     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
 xz:
-            05                                                                                                                              0x0d0c0b0a/imm32  # add to EAX
+  05  0x0d0c0b0a/imm32
 +error: 'xz' is two characters long which can look like raw hex bytes at a glance; use a different name
 
 :(scenario label_hex)
 % Hide_errors = true;
 == 0x1
-          # instruction                     effective address                                                   operand     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
 0xab:
-            05                                                                                                                              0x0d0c0b0a/imm32  # add to EAX
+  05  0x0d0c0b0a/imm32
 +error: '0xab' looks like a hex number; use a different name
 
 :(scenario label_negative_hex)
 % Hide_errors = true;
 == 0x1
-          # instruction                     effective address                                                   operand     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
  -a:  # indent to avoid looking like a trace_should_not_contain command for this scenario
-            05                                                                                                                              0x0d0c0b0a/imm32  # add to EAX
+    05  0x0d0c0b0a/imm32
 +error: '-a' starts with '-', which can be confused with a negative number; use a different name
 
 //: now that we have labels, we need to adjust segment size computation to
@@ -264,11 +249,11 @@ xz:
 
 :(scenario segment_size_ignores_labels)
 == code  # 0x09000074
-05/add 0x0d0c0b0a/imm32  # 5 bytes
-foo:                     # 0 bytes
+  05/add  0x0d0c0b0a/imm32  # 5 bytes
+foo:                      # 0 bytes
 == data  # 0x0a000079
 bar:
-00
+  00
 +transform: segment 1 begins at address 0x0a000079
 
 :(before "End num_bytes(curr) Special-cases")
diff --git a/subx/036global_variables.cc b/subx/036global_variables.cc
index e7c139ae..a5e15369 100644
--- a/subx/036global_variables.cc
+++ b/subx/036global_variables.cc
@@ -8,7 +8,7 @@
 
 :(scenario global_variable)
 == code
-b9/copy x/imm32  # copy to ECX
+b9  x/imm32
 == data
 x:
 00 00 00 00
@@ -129,7 +129,7 @@ bool has_metadata(const word& w, const string& m) {
 :(scenario global_variable_disallowed_in_jump)
 % Hide_errors = true;
 == code
-eb/jump x/disp8
+eb/jump  x/disp8
 == data
 x:
 00 00 00 00
@@ -140,7 +140,7 @@ x:
 :(scenario global_variable_disallowed_in_call)
 % Hide_errors = true;
 == code
-e8/call x/disp32
+e8/call  x/disp32
 == data
 x:
 00 00 00 00
diff --git a/subx/038---literal_strings.cc b/subx/038---literal_strings.cc
index b17947c0..5f2c61af 100644
--- a/subx/038---literal_strings.cc
+++ b/subx/038---literal_strings.cc
@@ -5,7 +5,7 @@
 
 :(scenario transform_literal_string)
 == code
-  b8/copy "test"/imm32  # copy to EAX
+b8/copy  "test"/imm32
 == data  # need to manually create this for now
 +transform: -- move literal strings to data segment
 +transform: adding global variable '__subx_global_1' containing "test"
diff --git a/subx/050write_stderr.subx b/subx/050write_stderr.subx
index ed06b7ff..51fd5a80 100644
--- a/subx/050write_stderr.subx
+++ b/subx/050write_stderr.subx
@@ -15,7 +15,7 @@ write-stderr:  # s : (address array byte) -> <void>
   53/push-EBX
   # write(2/stderr, (data) s+4, (size) *s)
     # fd = 2 (stderr)
-  bb/copy                         .               .             .           .             .           .           .               2/imm32           # copy to EBX
+  bb/copy-to-EBX  2/imm32
     # x = s+4
   8b/copy                         1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           1/r32/ECX   8/disp8         .                 # copy *(EBP+8) to ECX
   81          0/subop/add         3/mod/direct    1/rm32/ECX    .           .             .           .           .               4/imm32           # add to ECX
@@ -23,7 +23,7 @@ write-stderr:  # s : (address array byte) -> <void>
   8b/copy                         1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           2/r32/EDX   8/disp8         .                 # copy *(EBP+8) to EDX
   8b/copy                         0/mod/indirect  2/rm32/EDX    .           .             .           2/r32/EDX   .               .                 # copy *EDX to EDX
     # call write()
-  b8/copy                         .               .             .           .             .           .           .               4/imm32/write     # copy to EAX
+  b8/copy-to-EAX  4/imm32/write
   cd/syscall  0x80/imm8
   # restore registers
   5b/pop-to-EBX
diff --git a/subx/052kernel_string_equal.subx b/subx/052kernel_string_equal.subx
index b0b646c5..85aba0c0 100644
--- a/subx/052kernel_string_equal.subx
+++ b/subx/052kernel_string_equal.subx
@@ -24,7 +24,7 @@
   e8/call  run-tests/disp32  # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'.
   # 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                         .               .             .           .             .           .           .               1/imm32           # copy to EAX
+  b8/copy-to-EAX  1/imm32
   cd/syscall  0x80/imm8
 
 # compare a null-terminated ascii string with a more idiomatic length-prefixed byte array
@@ -63,15 +63,15 @@ kernel-string-equal:  # s : null-terminated ascii string, benchmark : length-pre
   8b/copy                         1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           6/r32/ESI   0xc/disp8       .                 # copy *(EBP+12) to ESI
   81          0/subop/add         3/mod/direct    6/rm32/ESI    .           .             .           .           .               4/imm32           # add to ESI
   # initialize loop counter i into ECX
-  b9/copy                         .               .             .           .             .           .           .               0/imm32/exit      # copy to ECX
+  b9/copy-to-ECX  0/imm32/exit
   # while (i/ECX < n/EDX)
 $kernel-string-equal:loop:
   39/compare                      3/mod/direct    1/rm32/ECX    .           .             .           2/r32/EDX   .               .                 # compare ECX with EDX
   74/jump-if-equal  $kernel-string-equal:break/disp8
     # c1/EAX, c2/EBX = *s, *benchmark
-  b8/copy  0/imm32  # clear EAX
+  b8/copy-to-EAX  0/imm32
   8a/copy                         0/mod/indirect  7/rm32/EDI    .           .             .           0/r32/EAX   .               .                 # copy byte at *EDI to lower byte of EAX
-  bb/copy  0/imm32  # clear EBX
+  bb/copy-to-EBX  0/imm32
   8a/copy                         0/mod/indirect  6/rm32/ESI    .           .             .           3/r32/EBX   .               .                 # copy byte at *ESI to lower byte of EBX
     # if (c1 == 0) return false
   3d/compare-EAX  0/imm32
@@ -87,16 +87,16 @@ $kernel-string-equal:loop:
   eb/jump  $kernel-string-equal:loop/disp8
 $kernel-string-equal:break:
   # if (*s/EDI == 0) return true
-  b8/copy  0/imm32  # clear EAX
+  b8/copy-to-EAX  0/imm32
   8a/copy                         0/mod/indirect  7/rm32/EDI    .           .             .           0/r32/EAX   .               .                 # copy byte at *EDI to lower byte of EAX
   3d/compare-EAX  0/imm32
   75/jump-if-not-equal  $kernel-string-equal:false/disp8
 $kernel-string-equal:true:
-  b8/copy                         .               .             .           .             .           .           .               1/imm32           # copy to EAX
+  b8/copy-to-EAX  1/imm32
   eb/jump  $kernel-string-equal:end/disp8
   # return false
 $kernel-string-equal:false:
-  b8/copy                         .               .             .           .             .           .           .               0/imm32           # copy to EAX
+  b8/copy-to-EAX  0/imm32
 
 $kernel-string-equal:end:
   # restore registers
diff --git a/subx/053new_segment.subx b/subx/053new_segment.subx
index fc0dfffc..f8524964 100644
--- a/subx/053new_segment.subx
+++ b/subx/053new_segment.subx
@@ -20,7 +20,7 @@
 
   # exit(EAX)
   89/copy                         3/mod/direct    3/rm32/EBX    .           .             .           0/r32/EAX   .               .                       # copy EAX to EBX
-  b8/copy                         .               .             .           .             .           .           .               1/imm32/exit            # copy to EAX
+  b8/copy-to-EAX  1/imm32/exit
   cd/syscall  0x80/imm8
 
 new-segment:  # len : int -> address
@@ -31,11 +31,11 @@ new-segment:  # len : int -> address
   # copy len to mmap-new-segment.len
   # TODO: compute mmap-new-segment+4 before runtime
   8b/copy                         1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           0/r32/EAX   8/disp8         .                       # copy *(EBP+8) to EAX
-  bb/copy                         .               .             .           .             .           .           .               mmap-new-segment/imm32  # copy to EBX
+  bb/copy-to-EBX  mmap-new-segment/imm32
   89/copy                         1/mod/*+disp8   3/rm32/EBX    .           .             .           0/r32/EAX   4/disp8         .                       # copy EAX to *(EBX+4)
   # mmap(mmap-new-segment)
-  bb/copy                         .               .             .           .             .           .           .               mmap-new-segment/imm32  # copy to EBX
-  b8/copy                         .               .             .           .             .           .           .               0x5a/imm32/mmap         # copy to EAX
+  bb/copy-to-EBX  mmap-new-segment/imm32
+  b8/copy-to-EAX  0x5a/imm32/mmap
   cd/syscall  0x80/imm8
   # epilog
   5b/pop-to-EBX
diff --git a/subx/054string_equal.subx b/subx/054string_equal.subx
index c66baf99..e132d0d2 100644
--- a/subx/054string_equal.subx
+++ b/subx/054string_equal.subx
@@ -10,7 +10,7 @@
   e8/call  run-tests/disp32  # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'.
   # 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                         .               .             .           .             .           .           .               1/imm32           # copy to EAX
+  b8/copy-to-EAX  1/imm32
   cd/syscall  0x80/imm8
 
 string-equal:  # s : string, benchmark : string -> EAX : boolean
@@ -46,7 +46,7 @@ string-equal:  # s : string, benchmark : string -> EAX : boolean
   75/jump-if-not-equal  $string-equal:false/disp8
 $string-equal:lengths:
   # var i/ECX : int = 0
-  b9/copy                         .               .             .           .             .           .           .               0/imm32           # copy to ECX
+  b9/copy-to-ECX  0/imm32
   # EBX = &b[i]
   43/inc-EBX
   # EAX = &s[i]
@@ -69,11 +69,11 @@ $string-equal:loop:
   eb/jump  $string-equal:loop/disp8
 $string-equal:true:
   # return true
-  b8/copy                         .               .             .           .             .           .           .               1/imm32           # copy to EAX
+  b8/copy-to-EAX  1/imm32
   eb/jump  $string-equal:end/disp8
 $string-equal:false:
   # return false
-  b8/copy                         .               .             .           .             .           .           .               0/imm32           # copy to EAX
+  b8/copy-to-EAX  0/imm32
 $string-equal:end:
   # restore registers
   5e/pop-to-ESI
diff --git a/subx/apps/crenshaw2-1.subx b/subx/apps/crenshaw2-1.subx
index 400a0bfe..d5bd2a01 100644
--- a/subx/apps/crenshaw2-1.subx
+++ b/subx/apps/crenshaw2-1.subx
@@ -27,8 +27,8 @@
     # discard arg
   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
   # exit(0)
-  bb/copy                         .               .             .           .             .           .           .               0/imm32           # copy to EBX
-  b8/copy                         .               .             .           .             .           .           .               1/imm32/exit      # copy to EAX
+  bb/copy-to-EBX  0/imm32
+  b8/copy-to-EAX  1/imm32/exit
   cd/syscall  0x80/imm8
 
 ## helpers
@@ -44,8 +44,8 @@ abort:  # s : (address array byte) -> <void>
     # discard arg
   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
   # exit(1)
-  bb/copy                         .               .             .           .             .           .           .               1/imm32           # copy to EBX
-  b8/copy                         .               .             .           .             .           .           .               1/imm32/exit      # copy to EAX
+  bb/copy-to-EBX  1/imm32
+  b8/copy-to-EAX  1/imm32/exit
   cd/syscall  0x80/imm8
 
 # print out "Error: #{s} expected\n" to stderr
@@ -92,7 +92,7 @@ write-stdout:  # s : (address array byte) -> <void>
   53/push-EBX
   # write(1/stdout, (data) s+4, (size) *s)
     # fd = 1 (stdout)
-  bb/copy                         .               .             .           .             .           .           .               1/imm32           # copy to EBX
+  bb/copy-to-EBX  1/imm32
     # x = s+4
   8b/copy                         1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           1/r32/ECX   8/disp8         .                 # copy *(EBP+8) to ECX
   81          0/subop/add         3/mod/direct    1/rm32/ECX    .           .             .           .           .               4/imm32           # add to ECX
@@ -100,7 +100,7 @@ write-stdout:  # s : (address array byte) -> <void>
   8b/copy                         1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           2/r32/EDX   8/disp8         .                 # copy *(EBP+8) to EDX
   8b/copy                         0/mod/indirect  2/rm32/EDX    .           .             .           2/r32/EDX   .               .                 # copy *EDX to EDX
     # call write()
-  b8/copy                         .               .             .           .             .           .           .               4/imm32/write     # copy to EAX
+  b8/copy-to-EAX  4/imm32/write
   cd/syscall  0x80/imm8
   # restore registers
   5b/pop-to-EBX
diff --git a/subx/apps/factorial.subx b/subx/apps/factorial.subx
index c3b63209..fa0d58b2 100644
--- a/subx/apps/factorial.subx
+++ b/subx/apps/factorial.subx
@@ -50,7 +50,7 @@ $run-main:
 $main-exit:
   # exit(EAX)
   89/copy                         3/mod/direct    3/rm32/EBX    .           .             .           0/r32/EAX   .               .                 # copy EAX to EBX
-  b8/copy                         .               .             .           .             .           .           .               1/imm32           # copy to EAX
+  b8/copy-to-EAX  1/imm32
   cd/syscall  0x80/imm8
 
 # factorial(n)
@@ -60,7 +60,7 @@ factorial:
   89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
   53/push-EBX
   # initialize EAX to 1 (base case)
-  b8/copy                         .               .             .           .             .           .           .               1/imm32           # copy to EAX
+  b8/copy-to-EAX  1/imm32
   # if (n <= 1) jump exit
   81          7/subop/compare     1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           .           8/disp8         1/imm32           # compare *(EBP+8)
   7e/jump-if-<=  $factorial:exit/disp8
diff --git a/subx/examples/ex1.subx b/subx/examples/ex1.subx
index 996ef955..444f872a 100644
--- a/subx/examples/ex1.subx
+++ b/subx/examples/ex1.subx
@@ -12,9 +12,9 @@
 # instruction                     effective address                                                   operand     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
-  bb/copy                         .               .             .           .             .           .           .               2a/imm32          # copy 42 to EBX
+  bb/copy-to-EBX  2a/imm32
   # exit(EBX)
-  b8/copy                         .               .             .           .             .           .           .               1/imm32           # copy to EAX
+  b8/copy-to-EAX  1/imm32
   cd/syscall  0x80/imm8
 
 # vim:nowrap:textwidth=0
diff --git a/subx/examples/ex10.subx b/subx/examples/ex10.subx
index 43b0e1d1..b179369f 100644
--- a/subx/examples/ex10.subx
+++ b/subx/examples/ex10.subx
@@ -30,7 +30,7 @@
   # exit(EAX)
 $exit:
   89/copy                         3/mod/direct    3/rm32/EBX    .           .             .           0/r32/EAX   .               .                 # copy EAX to EBX
-  b8/copy                         .               .             .           .             .           .           .               1/imm32           # copy to EAX
+  b8/copy-to-EAX  1/imm32
   cd/syscall  0x80/imm8
 
 # compare two null-terminated ascii strings
@@ -42,9 +42,9 @@ argv-equal:  # (s1, s2) : null-terminated ascii strings -> EAX : boolean
   # while (true)
 $argv-equal:loop:
     # c1/EAX, c2/EBX = *s1, *s2
-  b8/copy  0/imm32  # clear EAX
+  b8/copy-to-EAX  0/imm32
   8a/copy                         0/mod/indirect  1/rm32/ECX    .           .             .           0/r32/EAX   .               .                 # copy byte at *ECX to lower byte of EAX
-  bb/copy  0/imm32  # clear EBX
+  bb/copy-to-EBX  0/imm32
   8a/copy                         0/mod/indirect  2/rm32/EDX    .           .             .           3/r32/EBX   .               .                 # copy byte at *EDX to lower byte of EBX
     # if (c1 == 0) break
   3d/compare-EAX  0/imm32
@@ -62,11 +62,11 @@ $argv-equal:break:
   81          7/subop/compare     3/mod/direct    3/rm32/EBX    .           .             .           .           .               0/imm32           # compare EBX
   75/jump-if-not-equal  $argv-equal:false/disp8
 $argv-equal:success:
-  b8/copy                         .               .             .           .             .           .           .               1/imm32           # copy to EAX
+  b8/copy-to-EAX  1/imm32
   c3/return
   # return false
 $argv-equal:false:
-  b8/copy                         .               .             .           .             .           .           .               0/imm32           # copy to EAX
+  b8/copy-to-EAX  0/imm32
   c3/return
 
 # vim:nowrap:textwidth=0
diff --git a/subx/examples/ex11.subx b/subx/examples/ex11.subx
index 2ffdaad3..038bd4c6 100644
--- a/subx/examples/ex11.subx
+++ b/subx/examples/ex11.subx
@@ -24,7 +24,7 @@
   e8/call  run-tests/disp32  # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'.
   # exit(EAX)
   89/copy                         3/mod/direct    3/rm32/EBX    .           .             .           0/r32/EAX   .               .                 # copy EAX to EBX
-  b8/copy                         .               .             .           .             .           .           .               1/imm32           # copy to EAX
+  b8/copy-to-EAX  1/imm32
   cd/syscall  0x80/imm8
 
 # compare a null-terminated ascii string with a more idiomatic length-prefixed byte array
@@ -62,15 +62,15 @@ kernel-string-equal:  # s : null-terminated ascii string, benchmark : length-pre
   8b/copy                         1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           6/r32/ESI   0xc/disp8       .                 # copy *(EBP+12) to ESI
   81          0/subop/add         3/mod/direct    6/rm32/ESI    .           .             .           .           .               4/imm32           # add to ESI
   # initialize loop counter i into ECX
-  b9/copy                         .               .             .           .             .           .           .               0/imm32/exit      # copy to ECX
+  b9/copy-to-ECX  0/imm32/exit
   # while (i/ECX < n/EDX)
 $kernel-string-equal:loop:
   39/compare                      3/mod/direct    1/rm32/ECX    .           .             .           2/r32/EDX   .               .                 # compare ECX with EDX
   74/jump-if-equal  $kernel-string-equal:break/disp8
     # c1/EAX, c2/EBX = *s, *benchmark
-  b8/copy  0/imm32  # clear EAX
+  b8/copy-to-EAX  0/imm32
   8a/copy                         0/mod/indirect  7/rm32/EDI    .           .             .           0/r32/EAX   .               .                 # copy byte at *EDI to lower byte of EAX
-  bb/copy  0/imm32  # clear EBX
+  bb/copy-to-EBX  0/imm32
   8a/copy                         0/mod/indirect  6/rm32/ESI    .           .             .           3/r32/EBX   .               .                 # copy byte at *ESI to lower byte of EBX
     # if (c1 == 0) return false
   3d/compare-EAX  0/imm32
@@ -86,16 +86,16 @@ $kernel-string-equal:loop:
   eb/jump  $kernel-string-equal:loop/disp8
 $kernel-string-equal:break:
   # if (*s/EDI == 0) return true
-  b8/copy  0/imm32  # clear EAX
+  b8/copy-to-EAX  0/imm32
   8a/copy                         0/mod/indirect  7/rm32/EDI    .           .             .           0/r32/EAX   .               .                 # copy byte at *EDI to lower byte of EAX
   81          7/subop/compare     3/mod/direct    0/rm32/EAX    .           .             .           .           .               0/imm32           # compare EAX
   75/jump-if-not-equal  $kernel-string-equal:false/disp8
-  b8/copy                         .               .             .           .             .           .           .               1/imm32           # copy to EAX
+  b8/copy-to-EAX  1/imm32
 $kernel-string-equal:true:
   eb/jump  $kernel-string-equal:end/disp8
   # return false
 $kernel-string-equal:false:
-  b8/copy                         .               .             .           .             .           .           .               0/imm32           # copy to EAX
+  b8/copy-to-EAX  0/imm32
 
 $kernel-string-equal:end:
   # restore registers
@@ -314,7 +314,7 @@ write-stderr:  # s : (address array byte) -> <void>
   53/push-EBX
   # write(2/stderr, (data) s+4, (size) *s)
     # fd = 2 (stderr)
-  bb/copy                         .               .             .           .             .           .           .               2/imm32           # copy to EBX
+  bb/copy-to-EBX  2/imm32
     # x = s+4
   8b/copy                         1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           1/r32/ECX   8/disp8         .                 # copy *(EBP+8) to ECX
   81          0/subop/add         3/mod/direct    1/rm32/ECX    .           .             .           .           .               4/imm32           # add to ECX
@@ -322,7 +322,7 @@ write-stderr:  # s : (address array byte) -> <void>
   8b/copy                         1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           2/r32/EDX   8/disp8         .                 # copy *(EBP+8) to EDX
   8b/copy                         0/mod/indirect  2/rm32/EDX    .           .             .           2/r32/EDX   .               .                 # copy *EDX to EDX
     # call write()
-  b8/copy                         .               .             .           .             .           .           .               4/imm32/write     # copy to EAX
+  b8/copy-to-EAX  4/imm32/write
   cd/syscall  0x80/imm8
   # restore registers
   5b/pop-to-EBX
diff --git a/subx/examples/ex12.subx b/subx/examples/ex12.subx
index 1db660ed..ba760707 100644
--- a/subx/examples/ex12.subx
+++ b/subx/examples/ex12.subx
@@ -12,8 +12,8 @@
 # 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
 
   # mmap(0x1000)
-  bb/copy                         .               .             .           .             .           .           .               mmap-new-segment/imm32  # copy to EBX
-  b8/copy                         .               .             .           .             .           .           .               0x5a/imm32/mmap         # copy to EAX
+  bb/copy-to-EBX  mmap-new-segment/imm32
+  b8/copy-to-EAX  0x5a/imm32/mmap
   cd/syscall  0x80/imm8
 
   # store to *EAX
@@ -21,7 +21,7 @@
 
   # exit(EAX)
   89/copy                         3/mod/direct    3/rm32/EBX    .           .             .           0/r32/EAX   .               .                       # copy EAX to EBX
-  b8/copy                         .               .             .           .             .           .           .               1/imm32/exit            # copy to EAX
+  b8/copy-to-EAX  1/imm32/exit
   cd/syscall  0x80/imm8
 
 == data
diff --git a/subx/examples/ex2.subx b/subx/examples/ex2.subx
index 800674f1..3035b39f 100644
--- a/subx/examples/ex2.subx
+++ b/subx/examples/ex2.subx
@@ -11,10 +11,10 @@
 # instruction                     effective address                                                   operand     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
-  bb/copy                         .               .             .           .             .           .           .               1/imm32           # copy to EBX
+  bb/copy-to-EBX  1/imm32
   43/inc-EBX
   # exit(EBX)
-  b8/copy                         .               .             .           .             .           .           .               1/imm32           # copy to EAX
+  b8/copy-to-EAX  1/imm32
   cd/syscall  0x80/imm8
 
 # vim:nowrap:textwidth=0
diff --git a/subx/examples/ex3.subx b/subx/examples/ex3.subx
index bbb6f1a7..8496b9c2 100644
--- a/subx/examples/ex3.subx
+++ b/subx/examples/ex3.subx
@@ -12,9 +12,9 @@
 # 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
   # result: EBX = 0
-  bb/copy                         .               .             .           .             .           .           .               0/imm32           # copy to EBX
+  bb/copy-to-EBX  0/imm32
   # counter: ECX = 1
-  b9/copy                         .               .             .           .             .           .           .               1/imm32           # copy to ECX
+  b9/copy-to-ECX  1/imm32
 
 $loop:
   # while (counter <= 10)
@@ -29,7 +29,7 @@ $loop:
 
 $exit:
   # exit(EBX)
-  b8/copy                         .               .             .           .             .           .           .               1/imm32           # copy to EAX
+  b8/copy-to-EAX  1/imm32
   cd/syscall  0x80/imm8
 
 # vim:nowrap:textwidth=0
diff --git a/subx/examples/ex4.subx b/subx/examples/ex4.subx
index 946a4810..3c4f8949 100644
--- a/subx/examples/ex4.subx
+++ b/subx/examples/ex4.subx
@@ -11,28 +11,28 @@
 
   # read(stdin, x, 1)
     # fd = 0 (stdin)
-  bb/copy                         .               .             .           .             .           .           .               0/imm32           # copy to EBX
+  bb/copy-to-EBX  0/imm32
     # initialize x (location to write result to)
-  b9/copy                         .               .             .           .             .           .           .               x/imm32           # copy to ECX
+  b9/copy-to-ECX  x/imm32
     # size = 1 character
-  ba/copy                         .               .             .           .             .           .           .               1/imm32           # copy to EDX
+  ba/copy-to-EDX  1/imm32
     # read(fd, x, size)
-  b8/copy                         .               .             .           .             .           .           .               3/imm32/read      # copy to EAX
+  b8/copy-to-EAX  3/imm32/read
   cd/syscall  0x80/imm8
 
   # write(stdout, x, 1)
     # fd = 1 (stdout)
-  bb/copy                         .               .             .           .             .           .           .               1/imm32           # copy to EBX
+  bb/copy-to-EBX  1/imm32
     # initialize x (location to read from)
-  b9/copy                         .               .             .           .             .           .           .               x/imm32           # copy to ECX
+  b9/copy-to-ECX  x/imm32
     # size = 1 character
-  ba/copy                         .               .             .           .             .           .           .               1/imm32           # copy to EDX
+  ba/copy-to-EDX  1/imm32
     # write(fd, x, size)
-  b8/copy                         .               .             .           .             .           .           .               4/imm32/write     # copy to EAX
+  b8/copy-to-EAX  4/imm32/write
   cd/syscall  0x80/imm8
 
   # exit(EBX)
-  b8/copy                         .               .             .           .             .           .           .               1/imm32/exit      # copy to EAX
+  b8/copy-to-EAX  1/imm32/exit
   cd/syscall  0x80/imm8
 
 == data
diff --git a/subx/examples/ex5.subx b/subx/examples/ex5.subx
index d773b366..4dad3043 100644
--- a/subx/examples/ex5.subx
+++ b/subx/examples/ex5.subx
@@ -15,28 +15,28 @@
 
   # read(stdin, x, 1)
     # fd = 0 (stdin)
-  bb/copy                         .               .             .           .             .           .           .               0/imm32           # copy to EBX
+  bb/copy-to-EBX  0/imm32
     # initialize x (location to write result to)
   8d/copy-address                 1/mod/*+disp8   4/rm32/sib    4/base/ESP  4/index/none              1/r32/ECX   4/disp8         .                 # copy ESP+4 to ECX
     # size = 1 character
-  ba/copy                         .               .             .           .             .           .           .               1/imm32           # copy to EDX
+  ba/copy-to-EDX  1/imm32
     # read(fd, x, size)
-  b8/copy                         .               .             .           .             .           .           .               3/imm32/read      # copy to EAX
+  b8/copy-to-EAX  3/imm32/read
   cd/syscall  0x80/imm8
 
   # write(stdout, x, 1)
     # fd = 1 (stdout)
-  bb/copy                         .               .             .           .             .           .           .               1/imm32           # copy to EBX
+  bb/copy-to-EBX  1/imm32
     # initialize x (location to read from)
   8d/copy-address                 1/mod/*+disp8   4/rm32/sib    4/base/ESP  4/index/none              1/r32/ECX   4/disp8         .                 # copy ESP+4 to ECX
     # size = 1 character
-  ba/copy                         .               .             .           .             .           .           .               1/imm32           # copy to EDX
+  ba/copy-to-EDX  1/imm32
     # write(fd, x, size)
-  b8/copy                         .               .             .           .             .           .           .               4/imm32/write     # copy to EAX
+  b8/copy-to-EAX  4/imm32/write
   cd/syscall  0x80/imm8
 
   # exit(EBX)
-  b8/copy                         .               .             .           .             .           .           .               1/imm32/exit      # copy to EAX
+  b8/copy-to-EAX  1/imm32/exit
   cd/syscall  0x80/imm8
 
 # vim:nowrap:textwidth=0
diff --git a/subx/examples/ex6.subx b/subx/examples/ex6.subx
index 256aa47c..1c726c65 100644
--- a/subx/examples/ex6.subx
+++ b/subx/examples/ex6.subx
@@ -12,17 +12,17 @@
 
   # write(stdout, x, size)
     # fd = 1 (stdout)
-  bb/copy                         .               .             .           .             .           .           .               1/imm32           # copy to EBX
+  bb/copy-to-EBX  1/imm32
     # initialize x (location to write result to)
-  b9/copy                         .               .             .           .             .           .           .               x/imm32           # copy to ECX
+  b9/copy-to-ECX  x/imm32
     # initialize size
   8b/copy                         0/mod/indirect  5/rm32/.disp32            .             .           2/r32/EDX   size/disp32     .                 # copy *size to EDX
     # write(fd, x, size)
-  b8/copy                         .               .             .           .             .           .           .               4/imm32/write     # copy to EAX
+  b8/copy-to-EAX  4/imm32/write
   cd/syscall  0x80/imm8
 
   # exit(EBX)
-  b8/copy                         .               .             .           .             .           .           .               1/imm32/exit      # copy to EAX
+  b8/copy-to-EAX  1/imm32/exit
   cd/syscall  0x80/imm8
 
 == data
diff --git a/subx/examples/ex7.subx b/subx/examples/ex7.subx
index d5956ec9..841daf61 100644
--- a/subx/examples/ex7.subx
+++ b/subx/examples/ex7.subx
@@ -16,78 +16,78 @@
 # 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
 
   # creat(filename)
-  bb/copy                         .               .             .           .             .           .           .               filename/imm32          # copy to EBX
-  b9/copy                         .               .             .           .             .           .           .               0x180/imm32/fixed-perms # copy to ECX
-  b8/copy                         .               .             .           .             .           .           .               8/imm32/creat           # copy to EAX
+  bb/copy-to-EBX  filename/imm32
+  b9/copy-to-ECX  0x180/imm32/fixed-perms
+  b8/copy-to-EAX  8/imm32/creat
   cd/syscall  0x80/imm8
 
   # stream = open(filename, O_WRONLY, 0)  # we can't use 'fd' because it looks like a hex byte
-  bb/copy                         .               .             .           .             .           .           .               filename/imm32          # copy to EBX
-  b9/copy                         .               .             .           .             .           .           .               1/imm32/wronly          # copy to ECX
-  ba/copy                         .               .             .           .             .           .           .               0x180/imm32/fixed-perms # copy to EDX
-  b8/copy                         .               .             .           .             .           .           .               5/imm32/open            # copy to EAX
+  bb/copy-to-EBX  filename/imm32
+  b9/copy-to-ECX  1/imm32/wronly
+  ba/copy-to-EDX  0x180/imm32/fixed-perms
+  b8/copy-to-EAX  5/imm32/open
   cd/syscall  0x80/imm8
     # save stream
-  bb/copy                         .               .             .           .             .           .           .               stream/imm32            # copy to EBX
+  bb/copy-to-EBX  stream/imm32
   89/copy                         0/mod/indirect  3/rm32/EBX                                          0/r32/EAX                                           # copy EAX to *EBX
 
   # write(stream, "a", 1)
     # load stream
-  bb/copy                         .               .             .           .             .           .           .               stream/imm32            # copy to EBX
+  bb/copy-to-EBX  stream/imm32
   8b/copy                         0/mod/indirect  3/rm32/EBX                                          3/r32/EBX                                           # copy *EBX to EBX
     #
-  b9/copy                         .               .             .           .             .           .           .               a/imm32                 # copy to ECX
-  ba/copy                         .               .             .           .             .           .           .               1/imm32/size            # copy to EDX
-  b8/copy                         .               .             .           .             .           .           .               4/imm32/write           # copy to EAX
+  b9/copy-to-ECX  a/imm32
+  ba/copy-to-EDX  1/imm32/size
+  b8/copy-to-EAX  4/imm32/write
   cd/syscall  0x80/imm8
 
   # close(stream)
     # load stream
-  bb/copy                         .               .             .           .             .           .           .               stream/imm32            # copy to EBX
+  bb/copy-to-EBX  stream/imm32
   8b/copy                         0/mod/indirect  3/rm32/EBX                                          3/r32/EBX                                           # copy *EBX to EBX
     #
-  b8/copy                         .               .             .           .             .           .           .               6/imm32/close           # copy to EAX
+  b8/copy-to-EAX  6/imm32/close
   cd/syscall  0x80/imm8
 
   # stream = open(filename, O_RDONLY, 0)
-  bb/copy                         .               .             .           .             .           .           .               filename/imm32          # copy to EBX
-  b9/copy                         .               .             .           .             .           .           .               0/imm32/rdonly          # copy to ECX
-  ba/copy                         .               .             .           .             .           .           .               0x180/imm32/fixed-perms # copy to EDX
-  b8/copy                         .               .             .           .             .           .           .               5/imm32/open            # copy to EAX
+  bb/copy-to-EBX  filename/imm32
+  b9/copy-to-ECX  0/imm32/rdonly
+  ba/copy-to-EDX  0x180/imm32/fixed-perms
+  b8/copy-to-EAX  5/imm32/open
   cd/syscall  0x80/imm8
     # save stream
-  bb/copy                         .               .             .           .             .           .           .               stream/imm32            # copy to EBX
+  bb/copy-to-EBX  stream/imm32
   89/copy                         0/mod/indirect  3/rm32/EBX                                          0/r32/EAX                                           # copy EAX to *EBX
 
   # read(stream, b, 1)
     # load stream
-  bb/copy                         .               .             .           .             .           .           .               stream/imm32            # copy to EBX
+  bb/copy-to-EBX  stream/imm32
   8b/copy                         0/mod/indirect  3/rm32/EBX                                          3/r32/EBX                                           # copy *EBX to EBX
     #
-  b9/copy                         .               .             .           .             .           .           .               b/imm32                 # copy to ECX
-  ba/copy                         .               .             .           .             .           .           .               1/imm32/size            # copy to EDX
-  b8/copy                         .               .             .           .             .           .           .               3/imm32/read            # copy to EAX
+  b9/copy-to-ECX  b/imm32
+  ba/copy-to-EDX  1/imm32/size
+  b8/copy-to-EAX  3/imm32/read
   cd/syscall  0x80/imm8
 
   # close(stream)
     # load stream
-  bb/copy                         .               .             .           .             .           .           .               stream/imm32            # copy to EBX
+  bb/copy-to-EBX  stream/imm32
   8b/copy                         0/mod/indirect  3/rm32/EBX                                          3/r32/EBX                                           # copy *EBX to EBX
     #
-  b8/copy                         .               .             .           .             .           .           .               6/imm32/close           # copy to EAX
+  b8/copy-to-EAX  6/imm32/close
   cd/syscall  0x80/imm8
 
   # unlink(filename)
-  bb/copy                         .               .             .           .             .           .           .               filename/imm32          # copy to EBX
-  b8/copy                         .               .             .           .             .           .           .               0xa/imm32/unlink        # copy to EAX
+  bb/copy-to-EBX  filename/imm32
+  b8/copy-to-EAX  0xa/imm32/unlink
   cd/syscall  0x80/imm8
 
   # exit(b)
     # load b
-  bb/copy                         .               .             .           .             .           .           .               b/imm32                 # copy to EBX
+  bb/copy-to-EBX  b/imm32
   8b/copy                         0/mod/indirect  3/rm32/EBX                                          3/r32/EBX                                           # copy *EBX to EBX
     #
-  b8/copy                         .               .             .           .             .           .           .               1/imm32/exit            # copy to EAX
+  b8/copy-to-EAX  1/imm32/exit
   cd/syscall  0x80/imm8
 
 == data
diff --git a/subx/examples/ex8.subx b/subx/examples/ex8.subx
index 2726eea9..adc3f413 100644
--- a/subx/examples/ex8.subx
+++ b/subx/examples/ex8.subx
@@ -30,14 +30,14 @@
 
   # exit(EAX)
   89/copy                         3/mod/direct    3/rm32/EBX    .           .             .           0/r32/EAX   .               .                 # copy EAX to EBX
-  b8/copy                         .               .             .           .             .           .           .               1/imm32/exit      # copy to EAX
+  b8/copy-to-EAX  1/imm32/exit
   cd/syscall  0x80/imm8
 
 ascii-length:  # (s)
   # initialize s (EDX)
   8b/copy                         1/mod/*+disp8   4/rm32/sib    4/base/ESP  4/index/none              2/r32/EDX   4/disp8                           # copy *(ESP+4) to EDX
   # var result = 0 (EAX)
-  b8/copy                         .               .             .           .             .           .           .               0/imm32           # copy to EAX
+  b8/copy-to-EAX  0/imm32
 $ascii-length-loop:
   # var c = *s (ECX)
   8a/copy                         0/mod/*         2/rm32/EDX    .           .             .           1/r32/ECX   .               .                 # copy byte at *EDX to lower byte of ECX
diff --git a/subx/examples/ex9.subx b/subx/examples/ex9.subx
index 7e4132b2..fa2877df 100644
--- a/subx/examples/ex9.subx
+++ b/subx/examples/ex9.subx
@@ -33,7 +33,7 @@
   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
   # exit(EAX)
   89/copy                         3/mod/direct    3/rm32/EBX    .           .             .           0/r32/EAX   .               .                 # copy EAX to EBX
-  b8/copy                         .               .             .           .             .           .           .               1/imm32/exit      # copy to EAX
+  b8/copy-to-EAX  1/imm32/exit
   cd/syscall  0x80/imm8
 
 ascii-difference:  # (s1, s2) : null-terminated ascii strings