about summary refs log tree commit diff stats
path: root/subx/021byte_addressing.cc
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2019-01-05 01:07:37 -0800
committerKartik Agaram <vc@akkartik.com>2019-01-05 01:07:37 -0800
commit2eb174d697df06b303c45fb145b1434305a6ed5e (patch)
tree8a362f4369975737694cb2d063eabc1754a225fe /subx/021byte_addressing.cc
parentaa96ac23a626310242684d0ab510d0df358af179 (diff)
downloadmu-2eb174d697df06b303c45fb145b1434305a6ed5e.tar.gz
4908
Fix CI.

a) Update canonical binaries.
b) Fix an out-of-bounds access in `clear-stream`. This also required supporting
   a new instruction in `subx run` to load an imm8 into rm8.
Diffstat (limited to 'subx/021byte_addressing.cc')
-rw-r--r--subx/021byte_addressing.cc38
1 files changed, 37 insertions, 1 deletions
diff --git a/subx/021byte_addressing.cc b/subx/021byte_addressing.cc
index cffc4050..fba9a827 100644
--- a/subx/021byte_addressing.cc
+++ b/subx/021byte_addressing.cc
@@ -48,7 +48,7 @@ put_new(Name, "88", "copy r8 to r8/m8-at-r32");
   88  18                                      # copy BL to the byte at *EAX
 # ModR/M in binary: 00 (indirect mode) 011 (src BL) 000 (dest EAX)
 == 0x2000
-f0 cc bb aa  # 0xf0 with more data in following bytes
+f0 cc bb aa
 +run: copy BL to r8/m8-at-r32
 +run: effective address is 0x00002000 (EAX)
 +run: storing 0xab
@@ -114,3 +114,39 @@ case 0x8a: {  // copy r/m8 to r8
 +run: storing 0x44
 # ensure ESI is unchanged
 % CHECK_EQ(Reg[ESI].u, 0xaabbccdd);
+
+//:
+
+:(before "End Initialize Op Names")
+put_new(Name, "c6", "copy imm8 to r8/m8-at-r32 (mov)");
+
+:(scenario copy_imm8_to_mem_at_r32)
+% Reg[EAX].i = 0x2000;
+== 0x1
+# op  ModR/M  SIB   displacement  immediate
+  c6  00                          dd          # copy to the byte at *EAX
+# ModR/M in binary: 00 (indirect mode) 000 (unused) 000 (dest EAX)
+== 0x2000
+f0 cc bb aa
++run: copy imm8 to r8/m8-at-r32
++run: effective address is 0x00002000 (EAX)
++run: storing 0xdd
+% CHECK_EQ(0xaabbccdd, read_mem_u32(0x2000));
+
+:(before "End Single-Byte Opcodes")
+case 0xc6: {  // copy imm8 to r/m8
+  const uint8_t modrm = next();
+  const uint8_t src = next();
+  trace(90, "run") << "copy imm8 to r8/m8-at-r32" << end();
+  trace(90, "run") << "imm8 is 0x" << HEXWORD << src << end();
+  const uint8_t subop = (modrm>>3)&0x7;  // middle 3 'reg opcode' bits
+  if (subop != 0) {
+    cerr << "unrecognized subop for opcode c6: " << NUM(subop) << " (only 0/copy currently implemented)\n";
+    exit(1);
+  }
+  // use unsigned to zero-extend 8-bit value to 32 bits
+  uint8_t* dest = reinterpret_cast<uint8_t*>(effective_byte_address(modrm));
+  *dest = src;
+  trace(90, "run") << "storing 0x" << HEXBYTE << NUM(*dest) << end();
+  break;
+}