From f44c49c776b2199dd83b0de4e203a26bafa9c7ba Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Wed, 18 Oct 2017 01:42:51 -0700 Subject: 4080 subx: correct 'push' register. It gets its operand right from the opcode, not a new modrm byte. Have I misinterpreted any other instructions in this manner (`+rd` in the Intel manual)? --- html/subx/011direct_addressing.cc.html | 32 +++++++++++++++++++------------- subx/011direct_addressing.cc | 14 ++++++++++---- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/html/subx/011direct_addressing.cc.html b/html/subx/011direct_addressing.cc.html index dba0b3cf..a08f0e3f 100644 --- a/html/subx/011direct_addressing.cc.html +++ b/html/subx/011direct_addressing.cc.html @@ -286,25 +286,31 @@ if ('onhashchange' in window) { 221 % Reg[ESP].u = 0x64; 222 % Reg[EBX].i = 10; 223 # op ModRM SIB displacement immediate -224 50 03 # push EBX (reg 3) to stack +224 53 # push EBX (reg 3) to stack 225 +run: push reg 3 226 +run: pushing value 0x0000000a 227 +run: ESP is now 0x00000060 228 +run: contents at ESP: 0x0000000a 229 230 :(before "End Single-Byte Opcodes") -231 case 0x50: { -232 uint8_t modrm = next(); -233 uint8_t reg = modrm & 0x7; -234 trace(2, "run") << "push reg " << NUM(reg) << end(); -235 const int32_t val = Reg[reg].u; -236 trace(2, "run") << "pushing value 0x" << HEXWORD << val << end(); -237 Reg[ESP].u -= 4; -238 *reinterpret_cast<uint32_t*>(&Mem.at(Reg[ESP].u)) = val; -239 trace(2, "run") << "ESP is now 0x" << HEXWORD << Reg[ESP].u << end(); -240 trace(2, "run") << "contents at ESP: 0x" << HEXWORD << *reinterpret_cast<uint32_t*>(&Mem.at(Reg[ESP].u)) << end(); -241 break; -242 } +231 case 0x50: +232 case 0x51: +233 case 0x52: +234 case 0x53: +235 case 0x54: +236 case 0x55: +237 case 0x56: +238 case 0x57: { +239 uint8_t reg = op & 0x7; +240 trace(2, "run") << "push reg " << NUM(reg) << end(); +241 const int32_t val = Reg[reg].u; +242 trace(2, "run") << "pushing value 0x" << HEXWORD << val << end(); +243 Reg[ESP].u -= 4; +244 *reinterpret_cast<uint32_t*>(&Mem.at(Reg[ESP].u)) = val; +245 trace(2, "run") << "ESP is now 0x" << HEXWORD << Reg[ESP].u << end(); +246 trace(2, "run") << "contents at ESP: 0x" << HEXWORD << *reinterpret_cast<uint32_t*>(&Mem.at(Reg[ESP].u)) << end(); +247 break; +248 } diff --git a/subx/011direct_addressing.cc b/subx/011direct_addressing.cc index 2defcfec..827ce41e 100644 --- a/subx/011direct_addressing.cc +++ b/subx/011direct_addressing.cc @@ -221,16 +221,22 @@ case 0x89: { // copy r32 to r/m32 % Reg[ESP].u = 0x64; % Reg[EBX].i = 10; # op ModRM SIB displacement immediate - 50 03 # push EBX (reg 3) to stack + 53 # 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; +case 0x50: +case 0x51: +case 0x52: +case 0x53: +case 0x54: +case 0x55: +case 0x56: +case 0x57: { + uint8_t reg = op & 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(); -- cgit 1.4.1-2-gfad0