about summary refs log tree commit diff stats
path: root/subx/014indirect_addressing.cc
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2018-08-30 01:15:45 -0700
committerKartik Agaram <vc@akkartik.com>2018-08-30 01:15:45 -0700
commitf1b3d7b96749165d771b279b56cc05447b7db3e0 (patch)
tree0b9ce4b47746827ac9703bdf10d4976c98ae058d /subx/014indirect_addressing.cc
parent51e3e6cec3aea2589513e946f187d9c4bc8eadb3 (diff)
downloadmu-f1b3d7b96749165d771b279b56cc05447b7db3e0.tar.gz
4527 - reading commandline arguments
The new example ex9 doesn't yet work natively.

In the process I've emulated the kernel's role in providing args, implemented
a couple of instructions acting on 8-bit operands (useful for ASCII string
operations), and begun the start of the standard library (ascii_length
is the same as strlen).

At the level of SubX we're just only going to support ASCII.
Diffstat (limited to 'subx/014indirect_addressing.cc')
-rw-r--r--subx/014indirect_addressing.cc61
1 files changed, 60 insertions, 1 deletions
diff --git a/subx/014indirect_addressing.cc b/subx/014indirect_addressing.cc
index ede192fc..344da8de 100644
--- a/subx/014indirect_addressing.cc
+++ b/subx/014indirect_addressing.cc
@@ -363,7 +363,7 @@ put(name, "8b", "copy rm32 to r32");
 == 0x1  # code segment
 # op  ModR/M  SIB   displacement  immediate
   8b  18                                      # copy *EAX to EBX
-# ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX)
+# ModR/M in binary: 00 (indirect mode) 011 (src EBX) 000 (dest EAX)
 == 0x60  # data segment
 af 00 00 00  # 0xaf
 +run: copy r/m32 to EBX
@@ -381,6 +381,65 @@ case 0x8b: {  // copy r32 to r/m32
   break;
 }
 
+//:
+
+:(before "End Initialize Op Names(name)")
+put(name, "88", "copy r8 (lowermost byte of r32) to r8/m8-at-r32");
+
+:(scenario copy_r8_to_mem_at_r32)
+% Reg[EBX].i = 0xafafafaf;
+% Reg[EAX].i = 0x60;
+== 0x1
+# op  ModR/M  SIB   displacement  immediate
+  88  18                                      # copy just the lowermost byte of EBX to the byte at *EAX
+# ModR/M in binary: 00 (indirect mode) 011 (src EBX) 000 (dest EAX)
++run: copy lowermost byte of EBX to r8/m8-at-r32
++run: effective address is 0x60 (EAX)
++run: storing 0xaf
+% CHECK_EQ(0x000000af, read_mem_u32(0x60));
+
+:(before "End Single-Byte Opcodes")
+case 0x88: {  // copy r/m8 to r8
+  uint8_t modrm = next();
+  uint8_t reg2 = (modrm>>3)&0x7;
+  trace(90, "run") << "copy lowermost byte of " << rname(reg2) << " to r8/m8-at-r32" << end();
+  // use unsigned to zero-extend 8-bit value to 32 bits
+  uint8_t* arg1 = reinterpret_cast<uint8_t*>(effective_address(modrm));
+  *arg1 = Reg[reg2].u;
+  trace(90, "run") << "storing 0x" << HEXBYTE << NUM(*arg1) << end();
+  break;
+}
+
+//:
+
+:(before "End Initialize Op Names(name)")
+put(name, "8a", "copy r8/m8-at-r32 to r8 (lowermost byte of r32)");
+
+:(scenario copy_mem_at_r32_to_r8)
+% Reg[EBX].i = 0xaf;
+% Reg[EAX].i = 0x60;
+== 0x1
+# op  ModR/M  SIB   displacement  immediate
+  8a  18                                      # copy just the byte at *EAX to lowermost byte of EBX (clearing remaining bytes)
+# ModR/M in binary: 00 (indirect mode) 011 (dest EBX) 000 (src EAX)
+== 0x60  # data segment
+af ff ff ff  # 0xaf with more data in following bytes
++run: copy r8/m8-at-r32 to lowermost byte of EBX
++run: effective address is 0x60 (EAX)
++run: storing 0xaf
+
+:(before "End Single-Byte Opcodes")
+case 0x8a: {  // copy r/m8 to r8
+  uint8_t modrm = next();
+  uint8_t reg1 = (modrm>>3)&0x7;
+  trace(90, "run") << "copy r8/m8-at-r32 to lowermost byte of " << rname(reg1) << end();
+  // use unsigned to zero-extend 8-bit value to 32 bits
+  uint8_t* arg2 = reinterpret_cast<uint8_t*>(effective_address(modrm));
+  Reg[reg1].u = static_cast<uint32_t>(*arg2);
+  trace(90, "run") << "storing 0x" << HEXBYTE << NUM(*arg2) << end();
+  break;
+}
+
 //:: jump
 
 :(before "End Initialize Op Names(name)")