about summary refs log tree commit diff stats
path: root/subx
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2018-01-24 22:43:05 -0800
committerKartik K. Agaram <vc@akkartik.com>2018-01-24 22:43:05 -0800
commit0c6c7ff7142cb10532da21fb423f4d04efecf6c2 (patch)
tree57d38615b0c42198c77314c7c24edfd306123e08 /subx
parent9c1d07baecfa8ca479e8770416856c0e8f07c9dc (diff)
downloadmu-0c6c7ff7142cb10532da21fb423f4d04efecf6c2.tar.gz
4195
Diffstat (limited to 'subx')
-rw-r--r--subx/011direct_addressing.cc12
-rw-r--r--subx/012indirect_addressing.cc29
-rw-r--r--subx/014index_addressing.cc7
3 files changed, 20 insertions, 28 deletions
diff --git a/subx/011direct_addressing.cc b/subx/011direct_addressing.cc
index 7b4f9720..5ce620ad 100644
--- a/subx/011direct_addressing.cc
+++ b/subx/011direct_addressing.cc
@@ -28,19 +28,21 @@ int32_t* effective_address(uint8_t modrm) {
   uint8_t mod = (modrm>>6);
   // ignore middle 3 'reg opcode' bits
   uint8_t rm = modrm & 0x7;
-  int32_t* result = 0;
+  uint32_t addr = 0;
   switch (mod) {
   case 3:
     // mod 3 is just register direct addressing
     trace(2, "run") << "r/m32 is " << rname(rm) << end();
-    result = &Reg[rm].i;
-    break;
-  // End Mod Special-cases
+    return &Reg[rm].i;
+  // End Mod Special-cases(addr)
   default:
     cerr << "unrecognized mod bits: " << NUM(mod) << '\n';
     exit(1);
   }
-  return result;
+  //: other mods are indirect, and they'll set addr appropriately
+  assert(addr > 0);
+  assert(addr + sizeof(int32_t) <= Mem.size());
+  return reinterpret_cast<int32_t*>(&Mem.at(addr));  // rely on the host itself being in little-endian order
 }
 
 //:: subtract
diff --git a/subx/012indirect_addressing.cc b/subx/012indirect_addressing.cc
index f95b6960..ed478632 100644
--- a/subx/012indirect_addressing.cc
+++ b/subx/012indirect_addressing.cc
@@ -11,15 +11,14 @@
 +run: effective address is 0x60 (EAX)
 +run: storing 0x00000011
 
-:(before "End Mod Special-cases")
+:(before "End Mod Special-cases(addr)")
 case 0:  // indirect addressing
   switch (rm) {
   default:  // address in register
     trace(2, "run") << "effective address is 0x" << std::hex << Reg[rm].u << " (" << rname(rm) << ")" << end();
-    assert(Reg[rm].u + sizeof(int32_t) <= Mem.size());
-    result = reinterpret_cast<int32_t*>(&Mem.at(Reg[rm].u));  // rely on the host itself being in little-endian order
+    addr = Reg[rm].u;
     break;
-  // End Mod 0 Special-cases
+  // End Mod 0 Special-cases(addr)
   }
   break;
 
@@ -422,12 +421,10 @@ case 0x8f: {  // pop stack into r/m32
 +run: storing 0x00000011
 
 :(before "End Mod 0 Special-cases")
-case 5: {  // exception: mod 0b00 rm 0b101 => incoming disp32
-  uint32_t addr = imm32();
-  result = reinterpret_cast<int32_t*>(&Mem.at(addr));
+case 5:  // exception: mod 0b00 rm 0b101 => incoming disp32
+  addr = imm32();
   trace(2, "run") << "effective address is 0x" << std::hex << addr << " (disp32)" << end();
   break;
-}
 
 //:
 
@@ -442,18 +439,16 @@ case 5: {  // exception: mod 0b00 rm 0b101 => incoming disp32
 +run: effective address is 0x60 (EAX+disp8)
 +run: storing 0x00000011
 
-:(before "End Mod Special-cases")
+:(before "End Mod Special-cases(addr)")
 case 1:  // indirect + disp8 addressing
   switch (rm) {
     default: {
       int8_t disp = next();
-      uint32_t addr = Reg[rm].u + disp;
+      addr = Reg[rm].u + disp;
       trace(2, "run") << "effective address is 0x" << std::hex << addr << " (" << rname(rm) << "+disp8)" << end();
-      assert(addr + sizeof(int32_t) <= Mem.size());
-      result = reinterpret_cast<int32_t*>(&Mem.at(addr));  // rely on the host itself being in little-endian order
       break;
     }
-    // End Mod 1 Special-cases
+    // End Mod 1 Special-cases(addr)
   }
   break;
 
@@ -481,18 +476,16 @@ case 1:  // indirect + disp8 addressing
 +run: effective address is 0x60 (EAX+disp32)
 +run: storing 0x00000011
 
-:(before "End Mod Special-cases")
+:(before "End Mod Special-cases(addr)")
 case 2:  // indirect + disp32 addressing
   switch (rm) {
     default: {
       int32_t disp = imm32();
-      uint32_t addr = Reg[rm].u + disp;
+      addr = Reg[rm].u + disp;
       trace(2, "run") << "effective address is 0x" << std::hex << addr << " (" << rname(rm) << "+disp32)" << end();
-      assert(addr + sizeof(int32_t) <= Mem.size());
-      result = reinterpret_cast<int32_t*>(&Mem.at(addr));  // rely on the host itself being in little-endian order
       break;
     }
-    // End Mod 2 Special-cases
+    // End Mod 2 Special-cases(addr)
   }
   break;
 
diff --git a/subx/014index_addressing.cc b/subx/014index_addressing.cc
index 9e432863..37a4b9be 100644
--- a/subx/014index_addressing.cc
+++ b/subx/014index_addressing.cc
@@ -14,12 +14,9 @@
 +run: storing 0x00000011
 
 :(before "End Mod 0 Special-cases")
-case 4: {  // exception: mod 0b00 rm 0b100 => incoming SIB (scale-index-base) byte
-  uint32_t addr = effective_address_from_sib(mod);
-  if (addr == 0) break;
-  result = reinterpret_cast<int32_t*>(&Mem.at(addr));
+case 4:  // exception: mod 0b00 rm 0b100 => incoming SIB (scale-index-base) byte
+  addr = effective_address_from_sib(mod);
   break;
-}
 :(code)
 uint32_t effective_address_from_sib(uint8_t mod) {
   uint8_t sib = next();