about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--subx/001help.cc5
-rw-r--r--subx/010---vm.cc2
-rw-r--r--subx/011run.cc4
-rw-r--r--subx/013direct_addressing.cc86
-rw-r--r--subx/014indirect_addressing.cc18
-rw-r--r--subx/015immediate_addressing.cc32
-rw-r--r--subx/017jump_disp8.cc14
-rw-r--r--subx/018jump_disp16.cc14
-rw-r--r--subx/019functions.cc4
-rw-r--r--subx/020syscalls.cc2
-rw-r--r--subx/021byte_addressing.cc4
-rw-r--r--subx/030---operands.cc2
-rw-r--r--subx/031check_operands.cc14
-rw-r--r--subx/032check_operand_bounds.cc20
14 files changed, 113 insertions, 108 deletions
diff --git a/subx/001help.cc b/subx/001help.cc
index 64f02274..5f90abca 100644
--- a/subx/001help.cc
+++ b/subx/001help.cc
@@ -250,6 +250,11 @@ template<typename T> bool contains_key(T& map, typename T::key_type const& key)
 template<typename T> typename T::mapped_type& get_or_insert(T& map, typename T::key_type const& key) {
   return map[key];
 }
+template<typename T> typename T::mapped_type const& put_new(T& map, typename T::key_type const& key, typename T::mapped_type const& value) {
+  assert(map.find(key) == map.end());
+  map[key] = value;
+  return map[key];
+}
 //: The contract: any container that relies on get_or_insert should never call
 //: contains_key.
 
diff --git a/subx/010---vm.cc b/subx/010---vm.cc
index 41d98b82..c07cfc37 100644
--- a/subx/010---vm.cc
+++ b/subx/010---vm.cc
@@ -34,7 +34,7 @@ EIP = 1;  // preserve null pointer
 :(before "End Help Contents")
 cerr << "  registers\n";
 :(before "End Help Texts")
-put(Help, "registers",
+put_new(Help, "registers",
   "SubX currently supports eight 32-bit integer registers. From 0 to 7, they are:\n"
   "  EAX ECX EDX EBX ESP EBP ESI EDI\n"
   "ESP contains the top of the stack.\n"
diff --git a/subx/011run.cc b/subx/011run.cc
index 6dc1a09b..38c43681 100644
--- a/subx/011run.cc
+++ b/subx/011run.cc
@@ -4,7 +4,7 @@
 //: the VM. That comes later.)
 
 :(before "End Help Texts")
-put(Help, "syntax",
+put_new(Help, "syntax",
   "SubX programs consist of segments, each segment in turn consisting of lines.\n"
   "Line-endings are significant; each line should contain a single\n"
   "instruction, macro or directive.\n"
@@ -327,7 +327,7 @@ void parse_and_load(const string& text_bytes) {
 //:: run
 
 :(before "End Initialize Op Names(name)")
-put(name, "05", "add imm32 to EAX (add)");
+put_new(name, "05", "add imm32 to EAX (add)");
 
 //: our first opcode
 :(before "End Single-Byte Opcodes")
diff --git a/subx/013direct_addressing.cc b/subx/013direct_addressing.cc
index 71b869d2..d51059e4 100644
--- a/subx/013direct_addressing.cc
+++ b/subx/013direct_addressing.cc
@@ -1,7 +1,7 @@
 //: operating directly on a register
 
 :(before "End Initialize Op Names(name)")
-put(name, "01", "add r32 to rm32 (add)");
+put_new(name, "01", "add r32 to rm32 (add)");
 
 :(scenario add_r32_to_r32)
 % Reg[EAX].i = 0x10;
@@ -76,7 +76,7 @@ string rname(uint8_t r) {
 //:: subtract
 
 :(before "End Initialize Op Names(name)")
-put(name, "29", "subtract r32 from rm32 (sub)");
+put_new(name, "29", "subtract r32 from rm32 (sub)");
 
 :(scenario subtract_r32_from_r32)
 % Reg[EAX].i = 10;
@@ -102,7 +102,7 @@ case 0x29: {  // subtract r32 from r/m32
 //:: multiply
 
 :(before "End Initialize Op Names(name)")
-put(name, "f7", "negate/multiply rm32 (with EAX if necessary) depending on subop (neg/mul)");
+put_new(name, "f7", "negate/multiply rm32 (with EAX if necessary) depending on subop (neg/mul)");
 
 :(scenario multiply_eax_by_r32)
 % Reg[EAX].i = 4;
@@ -143,7 +143,7 @@ case 0xf7: {  // xor r32 with r/m32
 //:
 
 :(before "End Initialize Op Names(name)")
-put(name_0f, "af", "multiply rm32 into r32 (imul)");
+put_new(name_0f, "af", "multiply rm32 into r32 (imul)");
 
 :(scenario multiply_r32_into_r32)
 % Reg[EAX].i = 4;
@@ -169,7 +169,7 @@ case 0xaf: {  // multiply r32 into r/m32
 //:: and
 
 :(before "End Initialize Op Names(name)")
-put(name, "21", "rm32 = bitwise AND of r32 with rm32 (and)");
+put_new(name, "21", "rm32 = bitwise AND of r32 with rm32 (and)");
 
 :(scenario and_r32_with_r32)
 % Reg[EAX].i = 0x0a0b0c0d;
@@ -195,7 +195,7 @@ case 0x21: {  // and r32 with r/m32
 //:: or
 
 :(before "End Initialize Op Names(name)")
-put(name, "09", "rm32 = bitwise OR of r32 with rm32 (or)");
+put_new(name, "09", "rm32 = bitwise OR of r32 with rm32 (or)");
 
 :(scenario or_r32_with_r32)
 % Reg[EAX].i = 0x0a0b0c0d;
@@ -221,7 +221,7 @@ case 0x09: {  // or r32 with r/m32
 //:: xor
 
 :(before "End Initialize Op Names(name)")
-put(name, "31", "rm32 = bitwise XOR of r32 with rm32 (xor)");
+put_new(name, "31", "rm32 = bitwise XOR of r32 with rm32 (xor)");
 
 :(scenario xor_r32_with_r32)
 % Reg[EAX].i = 0x0a0b0c0d;
@@ -271,7 +271,7 @@ case 2: {  // not r/m32
 //:: compare (cmp)
 
 :(before "End Initialize Op Names(name)")
-put(name, "39", "compare: set SF if rm32 < r32 (cmp)");
+put_new(name, "39", "compare: set SF if rm32 < r32 (cmp)");
 
 :(scenario compare_r32_with_r32_greater)
 % Reg[EAX].i = 0x0a0b0c0d;
@@ -325,7 +325,7 @@ case 0x39: {  // set SF if r/m32 < r32
 //:: copy (mov)
 
 :(before "End Initialize Op Names(name)")
-put(name, "89", "copy r32 to rm32 (mov)");
+put_new(name, "89", "copy r32 to rm32 (mov)");
 
 :(scenario copy_r32_to_r32)
 % Reg[EBX].i = 0xaf;
@@ -351,7 +351,7 @@ case 0x89: {  // copy r32 to r/m32
 //:: xchg
 
 :(before "End Initialize Op Names(name)")
-put(name, "87", "swap the contents of r32 and rm32 (xchg)");
+put_new(name, "87", "swap the contents of r32 and rm32 (xchg)");
 
 :(scenario xchg_r32_with_r32)
 % Reg[EBX].i = 0xaf;
@@ -382,14 +382,14 @@ case 0x87: {  // exchange r32 with r/m32
 //:: increment
 
 :(before "End Initialize Op Names(name)")
-put(name, "40", "increment EAX (inc)");
-put(name, "41", "increment ECX (inc)");
-put(name, "42", "increment EDX (inc)");
-put(name, "43", "increment EBX (inc)");
-put(name, "44", "increment ESP (inc)");
-put(name, "45", "increment EBP (inc)");
-put(name, "46", "increment ESI (inc)");
-put(name, "47", "increment EDI (inc)");
+put_new(name, "40", "increment EAX (inc)");
+put_new(name, "41", "increment ECX (inc)");
+put_new(name, "42", "increment EDX (inc)");
+put_new(name, "43", "increment EBX (inc)");
+put_new(name, "44", "increment ESP (inc)");
+put_new(name, "45", "increment EBP (inc)");
+put_new(name, "46", "increment ESI (inc)");
+put_new(name, "47", "increment EDI (inc)");
 
 :(scenario increment_r32)
 % Reg[ECX].u = 0x1f;
@@ -416,7 +416,7 @@ case 0x47: {  // increment r32
 }
 
 :(before "End Initialize Op Names(name)")
-put(name, "ff", "increment/decrement/jump/push/call rm32 based on subop (inc/dec/jmp/push/call)");
+put_new(name, "ff", "increment/decrement/jump/push/call rm32 based on subop (inc/dec/jmp/push/call)");
 
 :(scenario increment_rm32)
 % Reg[EAX].u = 0x20;
@@ -448,14 +448,14 @@ case 0xff: {
 //:: decrement
 
 :(before "End Initialize Op Names(name)")
-put(name, "48", "decrement EAX (dec)");
-put(name, "49", "decrement ECX (dec)");
-put(name, "4a", "decrement EDX (dec)");
-put(name, "4b", "decrement EBX (dec)");
-put(name, "4c", "decrement ESP (dec)");
-put(name, "4d", "decrement EBP (dec)");
-put(name, "4e", "decrement ESI (dec)");
-put(name, "4f", "decrement EDI (dec)");
+put_new(name, "48", "decrement EAX (dec)");
+put_new(name, "49", "decrement ECX (dec)");
+put_new(name, "4a", "decrement EDX (dec)");
+put_new(name, "4b", "decrement EBX (dec)");
+put_new(name, "4c", "decrement ESP (dec)");
+put_new(name, "4d", "decrement EBP (dec)");
+put_new(name, "4e", "decrement ESI (dec)");
+put_new(name, "4f", "decrement EDI (dec)");
 
 :(scenario decrement_r32)
 % Reg[ECX].u = 0x1f;
@@ -503,14 +503,14 @@ case 1: {  // decrement r/m32
 //:: push
 
 :(before "End Initialize Op Names(name)")
-put(name, "50", "push EAX to stack (push)");
-put(name, "51", "push ECX to stack (push)");
-put(name, "52", "push EDX to stack (push)");
-put(name, "53", "push EBX to stack (push)");
-put(name, "54", "push ESP to stack (push)");
-put(name, "55", "push EBP to stack (push)");
-put(name, "56", "push ESI to stack (push)");
-put(name, "57", "push EDI to stack (push)");
+put_new(name, "50", "push EAX to stack (push)");
+put_new(name, "51", "push ECX to stack (push)");
+put_new(name, "52", "push EDX to stack (push)");
+put_new(name, "53", "push EBX to stack (push)");
+put_new(name, "54", "push ESP to stack (push)");
+put_new(name, "55", "push EBP to stack (push)");
+put_new(name, "56", "push ESI to stack (push)");
+put_new(name, "57", "push EDI to stack (push)");
 
 :(scenario push_r32)
 % Reg[ESP].u = 0x64;
@@ -541,14 +541,14 @@ case 0x57: {  // push r32 to stack
 //:: pop
 
 :(before "End Initialize Op Names(name)")
-put(name, "58", "pop top of stack to EAX (pop)");
-put(name, "59", "pop top of stack to ECX (pop)");
-put(name, "5a", "pop top of stack to EDX (pop)");
-put(name, "5b", "pop top of stack to EBX (pop)");
-put(name, "5c", "pop top of stack to ESP (pop)");
-put(name, "5d", "pop top of stack to EBP (pop)");
-put(name, "5e", "pop top of stack to ESI (pop)");
-put(name, "5f", "pop top of stack to EDI (pop)");
+put_new(name, "58", "pop top of stack to EAX (pop)");
+put_new(name, "59", "pop top of stack to ECX (pop)");
+put_new(name, "5a", "pop top of stack to EDX (pop)");
+put_new(name, "5b", "pop top of stack to EBX (pop)");
+put_new(name, "5c", "pop top of stack to ESP (pop)");
+put_new(name, "5d", "pop top of stack to EBP (pop)");
+put_new(name, "5e", "pop top of stack to ESI (pop)");
+put_new(name, "5f", "pop top of stack to EDI (pop)");
 
 :(scenario pop_r32)
 % Reg[ESP].u = 0x2000;
diff --git a/subx/014indirect_addressing.cc b/subx/014indirect_addressing.cc
index 8bcedbd3..09cd3b9a 100644
--- a/subx/014indirect_addressing.cc
+++ b/subx/014indirect_addressing.cc
@@ -28,7 +28,7 @@ case 0:  // indirect addressing
 //:
 
 :(before "End Initialize Op Names(name)")
-put(name, "03", "add rm32 to r32 (add)");
+put_new(name, "03", "add rm32 to r32 (add)");
 
 :(scenario add_mem_at_r32_to_r32)
 % Reg[EAX].i = 0x2000;
@@ -71,7 +71,7 @@ case 0x03: {  // add r/m32 to r32
 //:
 
 :(before "End Initialize Op Names(name)")
-put(name, "2b", "subtract rm32 from r32 (sub)");
+put_new(name, "2b", "subtract rm32 from r32 (sub)");
 
 :(scenario subtract_mem_at_r32_from_r32)
 % Reg[EAX].i = 0x2000;
@@ -114,7 +114,7 @@ case 0x2b: {  // subtract r/m32 from r32
 //:
 
 :(before "End Initialize Op Names(name)")
-put(name, "23", "r32 = bitwise AND of r32 with rm32 (and)");
+put_new(name, "23", "r32 = bitwise AND of r32 with rm32 (and)");
 
 :(scenario and_mem_at_r32_with_r32)
 % Reg[EAX].i = 0x2000;
@@ -157,7 +157,7 @@ case 0x23: {  // and r/m32 with r32
 //:
 
 :(before "End Initialize Op Names(name)")
-put(name, "0b", "r32 = bitwise OR of r32 with rm32 (or)");
+put_new(name, "0b", "r32 = bitwise OR of r32 with rm32 (or)");
 
 :(scenario or_mem_at_r32_with_r32)
 % Reg[EAX].i = 0x2000;
@@ -200,7 +200,7 @@ case 0x0b: {  // or r/m32 with r32
 //:
 
 :(before "End Initialize Op Names(name)")
-put(name, "33", "r32 = bitwise XOR of r32 with rm32 (xor)");
+put_new(name, "33", "r32 = bitwise XOR of r32 with rm32 (xor)");
 
 :(scenario xor_mem_at_r32_with_r32)
 % Reg[EAX].i = 0x2000;
@@ -284,7 +284,7 @@ ff 00 0f 0f  # 0x0f0f00ff
 //:
 
 :(before "End Initialize Op Names(name)")
-put(name, "3b", "compare: set SF if r32 < rm32 (cmp)");
+put_new(name, "3b", "compare: set SF if r32 < rm32 (cmp)");
 
 :(scenario compare_r32_with_mem_at_r32_greater)
 % Reg[EAX].i = 0x2000;
@@ -357,7 +357,7 @@ case 0x3b: {  // set SF if r32 < r/m32
 //:
 
 :(before "End Initialize Op Names(name)")
-put(name, "8b", "copy rm32 to r32 (mov)");
+put_new(name, "8b", "copy rm32 to r32 (mov)");
 
 :(scenario copy_mem_at_r32_to_r32)
 % Reg[EAX].i = 0x2000;
@@ -437,7 +437,7 @@ case 6: {  // push r/m32 to stack
 //:: pop
 
 :(before "End Initialize Op Names(name)")
-put(name, "8f", "pop top of stack to rm32 (pop)");
+put_new(name, "8f", "pop top of stack to rm32 (pop)");
 
 :(scenario pop_mem_at_r32)
 % Reg[EAX].i = 0x60;
@@ -581,7 +581,7 @@ case 2:  // indirect + disp32 addressing
 //:: lea
 
 :(before "End Initialize Op Names(name)")
-put(name, "8d", "copy address in rm32 into r32 (lea)");
+put_new(name, "8d", "copy address in rm32 into r32 (lea)");
 
 :(scenario lea)
 % Reg[EAX].u = 0x2000;
diff --git a/subx/015immediate_addressing.cc b/subx/015immediate_addressing.cc
index 7e6c6e28..c91d79fd 100644
--- a/subx/015immediate_addressing.cc
+++ b/subx/015immediate_addressing.cc
@@ -1,7 +1,7 @@
 //: instructions that (immediately) contain an argument to act with
 
 :(before "End Initialize Op Names(name)")
-put(name, "81", "combine rm32 with imm32 based on subop (add/sub/and/or/xor/cmp)");
+put_new(name, "81", "combine rm32 with imm32 based on subop (add/sub/and/or/xor/cmp)");
 
 :(scenario add_imm32_to_r32)
 % Reg[EBX].i = 1;
@@ -55,7 +55,7 @@ case 0x81: {  // combine imm32 with r/m32
 //:: subtract
 
 :(before "End Initialize Op Names(name)")
-put(name, "2d", "subtract imm32 from EAX (sub)");
+put_new(name, "2d", "subtract imm32 from EAX (sub)");
 
 :(scenario subtract_imm32_from_eax)
 % Reg[EAX].i = 0x0d0c0baa;
@@ -113,7 +113,7 @@ case 5: {
 //:: and
 
 :(before "End Initialize Op Names(name)")
-put(name, "25", "EAX = bitwise AND of imm32 with EAX (and)");
+put_new(name, "25", "EAX = bitwise AND of imm32 with EAX (and)");
 
 :(scenario and_imm32_with_eax)
 % Reg[EAX].i = 0xff;
@@ -171,7 +171,7 @@ case 4: {
 //:: or
 
 :(before "End Initialize Op Names(name)")
-put(name, "0d", "EAX = bitwise OR of imm32 with EAX (or)");
+put_new(name, "0d", "EAX = bitwise OR of imm32 with EAX (or)");
 
 :(scenario or_imm32_with_eax)
 % Reg[EAX].i = 0xd0c0b0a0;
@@ -227,7 +227,7 @@ case 1: {
 //:: xor
 
 :(before "End Initialize Op Names(name)")
-put(name, "35", "EAX = bitwise XOR of imm32 with EAX (xor)");
+put_new(name, "35", "EAX = bitwise XOR of imm32 with EAX (xor)");
 
 :(scenario xor_imm32_with_eax)
 % Reg[EAX].i = 0xddccb0a0;
@@ -283,7 +283,7 @@ case 6: {
 //:: compare (cmp)
 
 :(before "End Initialize Op Names(name)")
-put(name, "3d", "compare: set SF if EAX < imm32 (cmp)");
+put_new(name, "3d", "compare: set SF if EAX < imm32 (cmp)");
 
 :(scenario compare_imm32_with_eax_greater)
 % Reg[EAX].i = 0x0d0c0b0a;
@@ -413,14 +413,14 @@ case 7: {
 //:: copy (mov)
 
 :(before "End Initialize Op Names(name)")
-put(name, "b8", "copy imm32 to EAX (mov)");
-put(name, "b9", "copy imm32 to ECX (mov)");
-put(name, "ba", "copy imm32 to EDX (mov)");
-put(name, "bb", "copy imm32 to EBX (mov)");
-put(name, "bc", "copy imm32 to ESP (mov)");
-put(name, "bd", "copy imm32 to EBP (mov)");
-put(name, "be", "copy imm32 to ESI (mov)");
-put(name, "bf", "copy imm32 to EDI (mov)");
+put_new(name, "b8", "copy imm32 to EAX (mov)");
+put_new(name, "b9", "copy imm32 to ECX (mov)");
+put_new(name, "ba", "copy imm32 to EDX (mov)");
+put_new(name, "bb", "copy imm32 to EBX (mov)");
+put_new(name, "bc", "copy imm32 to ESP (mov)");
+put_new(name, "bd", "copy imm32 to EBP (mov)");
+put_new(name, "be", "copy imm32 to ESI (mov)");
+put_new(name, "bf", "copy imm32 to EDI (mov)");
 
 :(scenario copy_imm32_to_r32)
 == 0x1
@@ -447,7 +447,7 @@ case 0xbf: {  // copy imm32 to r32
 //:
 
 :(before "End Initialize Op Names(name)")
-put(name, "c7", "copy imm32 to rm32 (mov)");
+put_new(name, "c7", "copy imm32 to rm32 (mov)");
 
 :(scenario copy_imm32_to_mem_at_r32)
 % Reg[EBX].i = 0x60;
@@ -473,7 +473,7 @@ case 0xc7: {  // copy imm32 to r32
 //:: push
 
 :(before "End Initialize Op Names(name)")
-put(name, "68", "push imm32 to stack (push)");
+put_new(name, "68", "push imm32 to stack (push)");
 
 :(scenario push_imm32)
 % Reg[ESP].u = 0x14;
diff --git a/subx/017jump_disp8.cc b/subx/017jump_disp8.cc
index 67dc6656..c87b08a1 100644
--- a/subx/017jump_disp8.cc
+++ b/subx/017jump_disp8.cc
@@ -3,7 +3,7 @@
 //:: jump
 
 :(before "End Initialize Op Names(name)")
-put(name, "eb", "jump disp8 bytes away (jmp)");
+put_new(name, "eb", "jump disp8 bytes away (jmp)");
 
 :(scenario jump_rel8)
 == 0x1
@@ -27,7 +27,7 @@ case 0xeb: {  // jump rel8
 //:: jump if equal/zero
 
 :(before "End Initialize Op Names(name)")
-put(name, "74", "jump disp8 bytes away if equal, if ZF is set. (jcc/jz/je)");
+put_new(name, "74", "jump disp8 bytes away if equal, if ZF is set. (jcc/jz/je)");
 
 :(scenario je_rel8_success)
 % ZF = true;
@@ -66,7 +66,7 @@ case 0x74: {  // jump rel8 if ZF
 //:: jump if not equal/not zero
 
 :(before "End Initialize Op Names(name)")
-put(name, "75", "jump disp8 bytes away if not equal, if ZF is not set. (jcc/jnz/jne)");
+put_new(name, "75", "jump disp8 bytes away if not equal, if ZF is not set. (jcc/jnz/jne)");
 
 :(scenario jne_rel8_success)
 % ZF = false;
@@ -105,7 +105,7 @@ case 0x75: {  // jump rel8 unless ZF
 //:: jump if greater
 
 :(before "End Initialize Op Names(name)")
-put(name, "7f", "jump disp8 bytes away if greater, if ZF is unset and SF == OF. (jcc/jg/jnle)");
+put_new(name, "7f", "jump disp8 bytes away if greater, if ZF is unset and SF == OF. (jcc/jg/jnle)");
 
 :(scenario jg_rel8_success)
 % ZF = false;
@@ -148,7 +148,7 @@ case 0x7f: {  // jump rel8 if !SF and !ZF
 //:: jump if greater or equal
 
 :(before "End Initialize Op Names(name)")
-put(name, "7d", "jump disp8 bytes away if greater or equal, if SF == OF. (jcc/jge/jnl)");
+put_new(name, "7d", "jump disp8 bytes away if greater or equal, if SF == OF. (jcc/jge/jnl)");
 
 :(scenario jge_rel8_success)
 % SF = false;
@@ -189,7 +189,7 @@ case 0x7d: {  // jump rel8 if !SF
 //:: jump if lesser
 
 :(before "End Initialize Op Names(name)")
-put(name, "7c", "jump disp8 bytes away if lesser, if SF != OF. (jcc/jl/jnge)");
+put_new(name, "7c", "jump disp8 bytes away if lesser, if SF != OF. (jcc/jl/jnge)");
 
 :(scenario jl_rel8_success)
 % ZF = false;
@@ -232,7 +232,7 @@ case 0x7c: {  // jump rel8 if SF and !ZF
 //:: jump if lesser or equal
 
 :(before "End Initialize Op Names(name)")
-put(name, "7e", "jump disp8 bytes away if lesser or equal, if ZF is set or SF != OF. (jcc/jle/jng)");
+put_new(name, "7e", "jump disp8 bytes away if lesser or equal, if ZF is set or SF != OF. (jcc/jle/jng)");
 
 :(scenario jle_rel8_equal)
 % ZF = true;
diff --git a/subx/018jump_disp16.cc b/subx/018jump_disp16.cc
index b09c26b5..8a40cb9b 100644
--- a/subx/018jump_disp16.cc
+++ b/subx/018jump_disp16.cc
@@ -3,7 +3,7 @@
 //:: jump
 
 :(before "End Initialize Op Names(name)")
-put(name, "e9", "jump disp16 bytes away (jmp)");
+put_new(name, "e9", "jump disp16 bytes away (jmp)");
 
 :(scenario jump_rel16)
 == 0x1
@@ -33,7 +33,7 @@ int16_t imm16() {
 //:: jump if equal/zero
 
 :(before "End Initialize Op Names(name)")
-put(name_0f, "84", "jump disp16 bytes away if equal, if ZF is set. (jcc/jz/je)");
+put_new(name_0f, "84", "jump disp16 bytes away if equal, if ZF is set. (jcc/jz/je)");
 
 :(scenario je_rel16_success)
 % ZF = true;
@@ -72,7 +72,7 @@ case 0x84: {  // jump rel16 if ZF
 //:: jump if not equal/not zero
 
 :(before "End Initialize Op Names(name)")
-put(name_0f, "85", "jump disp16 bytes away if not equal, if ZF is not set. (jcc/jnz/jne)");
+put_new(name_0f, "85", "jump disp16 bytes away if not equal, if ZF is not set. (jcc/jnz/jne)");
 
 :(scenario jne_rel16_success)
 % ZF = false;
@@ -111,7 +111,7 @@ case 0x85: {  // jump rel16 unless ZF
 //:: jump if greater
 
 :(before "End Initialize Op Names(name)")
-put(name_0f, "8f", "jump disp16 bytes away if greater, if ZF is unset and SF == OF. (jcc/jg/jnle)");
+put_new(name_0f, "8f", "jump disp16 bytes away if greater, if ZF is unset and SF == OF. (jcc/jg/jnle)");
 
 :(scenario jg_rel16_success)
 % ZF = false;
@@ -154,7 +154,7 @@ case 0x8f: {  // jump rel16 if !SF and !ZF
 //:: jump if greater or equal
 
 :(before "End Initialize Op Names(name)")
-put(name_0f, "8d", "jump disp16 bytes away if greater or equal, if SF == OF. (jcc/jge/jnl)");
+put_new(name_0f, "8d", "jump disp16 bytes away if greater or equal, if SF == OF. (jcc/jge/jnl)");
 
 :(scenario jge_rel16_success)
 % SF = false;
@@ -195,7 +195,7 @@ case 0x8d: {  // jump rel16 if !SF
 //:: jump if lesser
 
 :(before "End Initialize Op Names(name)")
-put(name_0f, "8c", "jump disp16 bytes away if lesser, if SF != OF. (jcc/jl/jnge)");
+put_new(name_0f, "8c", "jump disp16 bytes away if lesser, if SF != OF. (jcc/jl/jnge)");
 
 :(scenario jl_rel16_success)
 % ZF = false;
@@ -238,7 +238,7 @@ case 0x8c: {  // jump rel16 if SF and !ZF
 //:: jump if lesser or equal
 
 :(before "End Initialize Op Names(name)")
-put(name_0f, "8e", "jump disp16 bytes away if lesser or equal, if ZF is set or SF != OF. (jcc/jle/jng)");
+put_new(name_0f, "8e", "jump disp16 bytes away if lesser or equal, if ZF is set or SF != OF. (jcc/jle/jng)");
 
 :(scenario jle_rel16_equal)
 % ZF = true;
diff --git a/subx/019functions.cc b/subx/019functions.cc
index a672dcfe..1eef7300 100644
--- a/subx/019functions.cc
+++ b/subx/019functions.cc
@@ -1,7 +1,7 @@
 //:: call
 
 :(before "End Initialize Op Names(name)")
-put(name, "e8", "call disp32 (call)");
+put_new(name, "e8", "call disp32 (call)");
 
 :(scenario call_disp32)
 % Reg[ESP].u = 0x64;
@@ -68,7 +68,7 @@ a0 00 00 00  # 0xa0
 //:: ret
 
 :(before "End Initialize Op Names(name)")
-put(name, "c3", "return from most recent unfinished call (ret)");
+put_new(name, "c3", "return from most recent unfinished call (ret)");
 
 :(scenario ret)
 % Reg[ESP].u = 0x2000;
diff --git a/subx/020syscalls.cc b/subx/020syscalls.cc
index 673e38a3..6d32ab90 100644
--- a/subx/020syscalls.cc
+++ b/subx/020syscalls.cc
@@ -1,5 +1,5 @@
 :(before "End Initialize Op Names(name)")
-put(name, "cd", "software interrupt (int)");
+put_new(name, "cd", "software interrupt (int)");
 
 :(before "End Single-Byte Opcodes")
 case 0xcd: {  // int imm8 (software interrupt)
diff --git a/subx/021byte_addressing.cc b/subx/021byte_addressing.cc
index b49718d1..685cf135 100644
--- a/subx/021byte_addressing.cc
+++ b/subx/021byte_addressing.cc
@@ -38,7 +38,7 @@ uint8_t* reg_8bit(uint8_t rm) {
 }
 
 :(before "End Initialize Op Names(name)")
-put(name, "88", "copy r8 to r8/m8-at-r32");
+put_new(name, "88", "copy r8 to r8/m8-at-r32");
 
 :(scenario copy_r8_to_mem_at_r32)
 % Reg[EBX].i = 0x224488ab;
@@ -70,7 +70,7 @@ case 0x88: {  // copy r8 to r/m8
 //:
 
 :(before "End Initialize Op Names(name)")
-put(name, "8a", "copy r8/m8-at-r32 to r8");
+put_new(name, "8a", "copy r8/m8-at-r32 to r8");
 
 :(scenario copy_mem_at_r32_to_r8)
 % Reg[EBX].i = 0xaabbcc0f;  // one nibble each of lowest byte set to all 0s and all 1s, to maximize value of this test
diff --git a/subx/030---operands.cc b/subx/030---operands.cc
index 4015174b..6d156035 100644
--- a/subx/030---operands.cc
+++ b/subx/030---operands.cc
@@ -13,7 +13,7 @@
 //: pack and order the bytes corresponding to the operands in an instruction.
 
 :(before "End Help Texts")
-put(Help, "instructions",
+put_new(Help, "instructions",
   "Each x86 instruction consists of an instruction or opcode and some number\n"
   "of operands.\n"
   "Each operand has a type. An instruction won't have more than one operand of\n"
diff --git a/subx/031check_operands.cc b/subx/031check_operands.cc
index 04dac5ba..e9c076ce 100644
--- a/subx/031check_operands.cc
+++ b/subx/031check_operands.cc
@@ -485,17 +485,17 @@ map</*op*/string, /*bitvector*/uint8_t> Permitted_operands_0f;
 //// Class C: just op and disp16
 //  imm32 imm8  disp32 |disp16  disp8 subop modrm
 //  0     0     0      |1       0     0     0
-put(Permitted_operands_0f, "84", 0x08);
-put(Permitted_operands_0f, "85", 0x08);
-put(Permitted_operands_0f, "8c", 0x08);
-put(Permitted_operands_0f, "8d", 0x08);
-put(Permitted_operands_0f, "8e", 0x08);
-put(Permitted_operands_0f, "8f", 0x08);
+put_new(Permitted_operands_0f, "84", 0x08);
+put_new(Permitted_operands_0f, "85", 0x08);
+put_new(Permitted_operands_0f, "8c", 0x08);
+put_new(Permitted_operands_0f, "8d", 0x08);
+put_new(Permitted_operands_0f, "8e", 0x08);
+put_new(Permitted_operands_0f, "8f", 0x08);
 
 //// Class M: using ModR/M byte
 //  imm32 imm8  disp32 |disp16  disp8 subop modrm
 //  0     0     0      |0       0     0     1
-put(Permitted_operands_0f, "af", 0x01);
+put_new(Permitted_operands_0f, "af", 0x01);
 
 :(code)
 void check_operands_0f(const line& inst, const word& op) {
diff --git a/subx/032check_operand_bounds.cc b/subx/032check_operand_bounds.cc
index 966913e9..b2276a8c 100644
--- a/subx/032check_operand_bounds.cc
+++ b/subx/032check_operand_bounds.cc
@@ -9,17 +9,17 @@
 :(before "End Globals")
 map<string, uint32_t> Operand_bound;
 :(before "End One-time Setup")
-put(Operand_bound, "subop", 1<<3);
-put(Operand_bound, "mod", 1<<2);
-put(Operand_bound, "rm32", 1<<3);
-put(Operand_bound, "base", 1<<3);
-put(Operand_bound, "index", 1<<3);
-put(Operand_bound, "scale", 1<<2);
-put(Operand_bound, "r32", 1<<3);
-put(Operand_bound, "disp8", 1<<8);
-put(Operand_bound, "disp16", 1<<16);
+put_new(Operand_bound, "subop", 1<<3);
+put_new(Operand_bound, "mod", 1<<2);
+put_new(Operand_bound, "rm32", 1<<3);
+put_new(Operand_bound, "base", 1<<3);
+put_new(Operand_bound, "index", 1<<3);
+put_new(Operand_bound, "scale", 1<<2);
+put_new(Operand_bound, "r32", 1<<3);
+put_new(Operand_bound, "disp8", 1<<8);
+put_new(Operand_bound, "disp16", 1<<16);
 // no bound needed for disp32
-put(Operand_bound, "imm8", 1<<8);
+put_new(Operand_bound, "imm8", 1<<8);
 // no bound needed for imm32
 
 :(before "Pack Operands(segment code)")