about summary refs log tree commit diff stats
path: root/subx
diff options
context:
space:
mode:
Diffstat (limited to 'subx')
-rw-r--r--subx/011direct_addressing.cc26
-rw-r--r--subx/012indirect_addressing.cc41
-rw-r--r--subx/013immediate_addressing.cc22
3 files changed, 82 insertions, 7 deletions
diff --git a/subx/011direct_addressing.cc b/subx/011direct_addressing.cc
index f474ac99..2defcfec 100644
--- a/subx/011direct_addressing.cc
+++ b/subx/011direct_addressing.cc
@@ -214,3 +214,29 @@ case 0x89: {  // copy r32 to r/m32
   trace(2, "run") << "storing 0x" << HEXWORD << *arg1 << end();
   break;
 }
+
+//:: push
+
+:(scenario push_r32)
+% Reg[ESP].u = 0x64;
+% Reg[EBX].i = 10;
+# op  ModRM   SIB   displacement  immediate
+  50  03                                      # push EBX (reg 3) to stack
++run: push reg 3
++run: pushing value 0x0000000a
++run: ESP is now 0x00000060
++run: contents at ESP: 0x0000000a
+
+:(before "End Single-Byte Opcodes")
+case 0x50: {
+  uint8_t modrm = next();
+  uint8_t reg = modrm & 0x7;
+  trace(2, "run") << "push reg " << NUM(reg) << end();
+  const int32_t val = Reg[reg].u;
+  trace(2, "run") << "pushing value 0x" << HEXWORD << val << end();
+  Reg[ESP].u -= 4;
+  *reinterpret_cast<uint32_t*>(&Mem.at(Reg[ESP].u)) = val;
+  trace(2, "run") << "ESP is now 0x" << HEXWORD << Reg[ESP].u << end();
+  trace(2, "run") << "contents at ESP: 0x" << HEXWORD << *reinterpret_cast<uint32_t*>(&Mem.at(Reg[ESP].u)) << end();
+  break;
+}
diff --git a/subx/012indirect_addressing.cc b/subx/012indirect_addressing.cc
index 1bf5e378..b4821856 100644
--- a/subx/012indirect_addressing.cc
+++ b/subx/012indirect_addressing.cc
@@ -327,13 +327,40 @@ case 0xff: {  // jump to r/m32
   uint8_t modrm = next();
   uint8_t subop = (modrm>>3)&0x7;  // middle 3 'reg opcode' bits
   switch (subop) {
-  case 4:
-    trace(2, "run") << "jump to effective address" << end();
-    int32_t* arg2 = effective_address(modrm);
-    EIP = *arg2;
-    trace(2, "run") << "jumping to 0x" << HEXWORD << EIP << end();
-    break;
-  // End Op ff Subops
+    case 4: {
+      trace(2, "run") << "jump to effective address" << end();
+      int32_t* arg2 = effective_address(modrm);
+      EIP = *arg2;
+      trace(2, "run") << "jumping to 0x" << HEXWORD << EIP << end();
+      break;
+    }
+    // End Op ff Subops
   }
   break;
 }
+
+//:: push
+
+:(scenario push_mem_at_r32)
+% Reg[0].i = 0x60;
+% SET_WORD_IN_MEM(0x60, 0x000000af);
+% Reg[ESP].u = 0x14;
+# op  ModRM   SIB   displacement  immediate
+  ff  30                                      # push *EAX (reg 0) to stack
++run: push effective address
++run: effective address is mem at address 0x60 (reg 0)
++run: ESP is now 0x00000010
++run: contents at ESP: 0x000000af
+
+:(before "End Op ff Subops")
+case 6: {
+  trace(2, "run") << "push effective address" << end();
+  const int32_t* val = effective_address(modrm);
+  trace(2, "run") << "pushing value 0x" << HEXWORD << *val << end();
+  Reg[ESP].u -= 4;
+  *reinterpret_cast<uint32_t*>(&Mem.at(Reg[ESP].u)) = *val;
+  trace(2, "run") << "ESP is now 0x" << HEXWORD << Reg[ESP].u << end();
+  trace(2, "run") << "contents at ESP: 0x" << HEXWORD << *reinterpret_cast<uint32_t*>(&Mem.at(Reg[ESP].u)) << end();
+  break;
+}
+
diff --git a/subx/013immediate_addressing.cc b/subx/013immediate_addressing.cc
index dd1ce4c0..2e4b459a 100644
--- a/subx/013immediate_addressing.cc
+++ b/subx/013immediate_addressing.cc
@@ -350,6 +350,7 @@ case 0xb8: {  // copy imm32 to r32
 }
 
 //:
+
 :(scenario copy_imm32_to_mem_at_r32)
 % Reg[3].i = 0x60;
 # op  ModRM   SIB   displacement  immediate
@@ -366,3 +367,24 @@ case 0xc7: {  // copy imm32 to r32
   *arg1 = arg2;
   break;
 }
+
+//:: push
+
+:(scenario push_imm32)
+% Reg[ESP].u = 0x14;
+# op  ModRM   SIB   displacement  immediate
+  68                              af 00 00 00  # push *EAX (reg 0) to stack
++run: push imm32 0x000000af
++run: ESP is now 0x00000010
++run: contents at ESP: 0x000000af
+
+:(before "End Single-Byte Opcodes")
+case 0x68: {
+  int32_t val = imm32();
+  trace(2, "run") << "push imm32 0x" << HEXWORD << val << end();
+  Reg[ESP].u -= 4;
+  *reinterpret_cast<uint32_t*>(&Mem.at(Reg[ESP].u)) = val;
+  trace(2, "run") << "ESP is now 0x" << HEXWORD << Reg[ESP].u << end();
+  trace(2, "run") << "contents at ESP: 0x" << HEXWORD << *reinterpret_cast<uint32_t*>(&Mem.at(Reg[ESP].u)) << end();
+  break;
+}