From 8a0268317fbce2baa2e5119c796750ea6c80a813 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Wed, 18 Oct 2017 02:27:56 -0700 Subject: [PATCH] 4084 subx: extract helpers for 'push' and 'pop'. We will be using them in 'call' and 'ret' as well. --- html/subx/011direct_addressing.cc.html | 112 ++++++++++++---------- html/subx/012indirect_addressing.cc.html | 75 +++++++-------- html/subx/013immediate_addressing.cc.html | 2 +- subx/011direct_addressing.cc | 32 ++++--- subx/012indirect_addressing.cc | 19 ++-- 5 files changed, 119 insertions(+), 121 deletions(-) diff --git a/html/subx/011direct_addressing.cc.html b/html/subx/011direct_addressing.cc.html index ba7a1e3b..7c348d47 100644 --- a/html/subx/011direct_addressing.cc.html +++ b/html/subx/011direct_addressing.cc.html @@ -287,59 +287,65 @@ if ('onhashchange' in window) { 222 % Reg[EBX].i = 0x0000000a; 223 # op ModRM SIB displacement immediate 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 case 0x51: -233 case 0x52: -234 case 0x53: -235 case 0x54: -236 case 0x55: -237 case 0x56: -238 case 0x57: { // push r32 to stack -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 } -249 -250 //:: pop -251 -252 :(scenario pop_r32) -253 % Reg[ESP].u = 0x60; -254 % SET_WORD_IN_MEM(0x60, 0x0000000a); -255 # op ModRM SIB displacement immediate -256 5b # pop stack to EBX (reg 3) -257 +run: pop into reg 3 -258 +run: popping value 0x0000000a -259 +run: ESP is now 0x00000064 -260 -261 :(before "End Single-Byte Opcodes") -262 case 0x58: -263 case 0x59: -264 case 0x5a: -265 case 0x5b: -266 case 0x5c: -267 case 0x5d: -268 case 0x5e: -269 case 0x5f: { // pop stack into r32 -270 uint8_t reg = op & 0x7; -271 trace(2, "run") << "pop into reg " << NUM(reg) << end(); -272 Reg[reg].u = *reinterpret_cast<uint32_t*>(&Mem.at(Reg[ESP].u)); -273 trace(2, "run") << "popping value 0x" << HEXWORD << Reg[reg].u << end(); -274 Reg[ESP].u += 4; -275 trace(2, "run") << "ESP is now 0x" << HEXWORD << Reg[ESP].u << end(); -276 break; -277 } +225 +run: push reg 3 +226 +run: decrementing ESP to 0x00000060 +227 +run: pushing value 0x0000000a +228 +229 :(before "End Single-Byte Opcodes") +230 case 0x50: +231 case 0x51: +232 case 0x52: +233 case 0x53: +234 case 0x54: +235 case 0x55: +236 case 0x56: +237 case 0x57: { // push r32 to stack +238 uint8_t reg = op & 0x7; +239 trace(2, "run") << "push reg " << NUM(reg) << end(); +240 push(Reg[reg].u); +241 break; +242 } +243 :(code) +244 void push(uint32_t val) { +245 Reg[ESP].u -= 4; +246 trace(2, "run") << "decrementing ESP to 0x" << HEXWORD << Reg[ESP].u << end(); +247 trace(2, "run") << "pushing value 0x" << HEXWORD << val << end(); +248 *reinterpret_cast<uint32_t*>(&Mem.at(Reg[ESP].u)) = val; +249 } +250 +251 //:: pop +252 +253 :(scenario pop_r32) +254 % Reg[ESP].u = 0x60; +255 % SET_WORD_IN_MEM(0x60, 0x0000000a); +256 # op ModRM SIB displacement immediate +257 5b # pop stack to EBX (reg 3) +258 +run: pop into reg 3 +259 +run: popping value 0x0000000a +260 +run: incrementing ESP to 0x00000064 +261 +262 :(before "End Single-Byte Opcodes") +263 case 0x58: +264 case 0x59: +265 case 0x5a: +266 case 0x5b: +267 case 0x5c: +268 case 0x5d: +269 case 0x5e: +270 case 0x5f: { // pop stack into r32 +271 uint8_t reg = op & 0x7; +272 trace(2, "run") << "pop into reg " << NUM(reg) << end(); +273 Reg[reg].u = pop(); +274 break; +275 } +276 :(code) +277 uint32_t pop() { +278 uint32_t result = *reinterpret_cast<uint32_t*>(&Mem.at(Reg[ESP].u)); +279 trace(2, "run") << "popping value 0x" << HEXWORD << result << end(); +280 Reg[ESP].u += 4; +281 trace(2, "run") << "incrementing ESP to 0x" << HEXWORD << Reg[ESP].u << end(); +282 return result; +283 } diff --git a/html/subx/012indirect_addressing.cc.html b/html/subx/012indirect_addressing.cc.html index 35dd62ab..781b9ad2 100644 --- a/html/subx/012indirect_addressing.cc.html +++ b/html/subx/012indirect_addressing.cc.html @@ -412,53 +412,46 @@ if ('onhashchange' in window) { 347 % Reg[ESP].u = 0x14; 348 # op ModRM SIB displacement immediate 349 ff 30 # push *EAX (reg 0) to stack -350 +run: push effective address +350 +run: push effective address 351 +run: effective address is mem at address 0x60 (reg 0) -352 +run: ESP is now 0x00000010 -353 +run: contents at ESP: 0x000000af +352 +run: decrementing ESP to 0x00000010 +353 +run: pushing value 0x000000af 354 355 :(before "End Op ff Subops") 356 case 6: { 357 trace(2, "run") << "push effective address" << end(); 358 const int32_t* val = effective_address(modrm); -359 trace(2, "run") << "pushing value 0x" << HEXWORD << *val << end(); -360 Reg[ESP].u -= 4; -361 *reinterpret_cast<uint32_t*>(&Mem.at(Reg[ESP].u)) = *val; -362 trace(2, "run") << "ESP is now 0x" << HEXWORD << Reg[ESP].u << end(); -363 trace(2, "run") << "contents at ESP: 0x" << HEXWORD << *reinterpret_cast<uint32_t*>(&Mem.at(Reg[ESP].u)) << end(); -364 break; -365 } -366 -367 //:: pop -368 -369 :(scenario pop_mem_at_r32) -370 % Reg[0].i = 0x60; -371 % Reg[ESP].u = 0x10; -372 % SET_WORD_IN_MEM(0x10, 0x00000030); -373 # op ModRM SIB displacement immediate -374 8f 00 # pop stack into *EAX (reg 0) -375 +run: pop into effective address -376 +run: effective address is mem at address 0x60 (reg 0) -377 +run: storing 0x00000030 -378 +run: ESP is now 0x00000014 -379 -380 :(before "End Single-Byte Opcodes") -381 case 0x8f: { // pop stack into r/m32 -382 uint8_t modrm = next(); -383 uint8_t subop = (modrm>>3)&0x7; -384 switch (subop) { -385 ¦ case 0: { -386 ¦ ¦ trace(2, "run") << "pop into effective address" << end(); -387 ¦ ¦ int32_t* dest = effective_address(modrm); -388 ¦ ¦ *dest = *reinterpret_cast<uint32_t*>(&Mem.at(Reg[ESP].u)); -389 ¦ ¦ trace(2, "run") << "storing 0x" << HEXWORD << *dest << end(); -390 ¦ ¦ Reg[ESP].u += 4; -391 ¦ ¦ trace(2, "run") << "ESP is now 0x" << HEXWORD << Reg[ESP].u << end(); -392 ¦ ¦ break; -393 ¦ } -394 } -395 break; -396 } +359 push(*val); +360 break; +361 } +362 +363 //:: pop +364 +365 :(scenario pop_mem_at_r32) +366 % Reg[0].i = 0x60; +367 % Reg[ESP].u = 0x10; +368 % SET_WORD_IN_MEM(0x10, 0x00000030); +369 # op ModRM SIB displacement immediate +370 8f 00 # pop stack into *EAX (reg 0) +371 +run: pop into effective address +372 +run: effective address is mem at address 0x60 (reg 0) +373 +run: popping value 0x00000030 +374 +run: incrementing ESP to 0x00000014 +375 +376 :(before "End Single-Byte Opcodes") +377 case 0x8f: { // pop stack into r/m32 +378 uint8_t modrm = next(); +379 uint8_t subop = (modrm>>3)&0x7; +380 switch (subop) { +381 ¦ case 0: { +382 ¦ ¦ trace(2, "run") << "pop into effective address" << end(); +383 ¦ ¦ int32_t* dest = effective_address(modrm); +384 ¦ ¦ *dest = pop(); +385 ¦ ¦ break; +386 ¦ } +387 } +388 break; +389 } diff --git a/html/subx/013immediate_addressing.cc.html b/html/subx/013immediate_addressing.cc.html index 80939a21..e8c646aa 100644 --- a/html/subx/013immediate_addressing.cc.html +++ b/html/subx/013immediate_addressing.cc.html @@ -440,7 +440,7 @@ if ('onhashchange' in window) { 376 % Reg[ESP].u = 0x14; 377 # op ModRM SIB displacement immediate 378 68 af 00 00 00 # push *EAX (reg 0) to stack -379 +run: push imm32 0x000000af +379 +run: push imm32 0x000000af 380 +run: ESP is now 0x00000010 381 +run: contents at ESP: 0x000000af 382 diff --git a/subx/011direct_addressing.cc b/subx/011direct_addressing.cc index b3f234b3..9e5f6e80 100644 --- a/subx/011direct_addressing.cc +++ b/subx/011direct_addressing.cc @@ -223,9 +223,8 @@ case 0x89: { // copy r32 to r/m32 # op ModRM SIB displacement immediate 53 # push EBX (reg 3) to stack +run: push reg 3 ++run: decrementing ESP to 0x00000060 +run: pushing value 0x0000000a -+run: ESP is now 0x00000060 -+run: contents at ESP: 0x0000000a :(before "End Single-Byte Opcodes") case 0x50: @@ -238,14 +237,16 @@ case 0x56: case 0x57: { // push r32 to stack 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(); - Reg[ESP].u -= 4; - *reinterpret_cast(&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(&Mem.at(Reg[ESP].u)) << end(); + push(Reg[reg].u); break; } +:(code) +void push(uint32_t val) { + Reg[ESP].u -= 4; + trace(2, "run") << "decrementing ESP to 0x" << HEXWORD << Reg[ESP].u << end(); + trace(2, "run") << "pushing value 0x" << HEXWORD << val << end(); + *reinterpret_cast(&Mem.at(Reg[ESP].u)) = val; +} //:: pop @@ -256,7 +257,7 @@ case 0x57: { // push r32 to stack 5b # pop stack to EBX (reg 3) +run: pop into reg 3 +run: popping value 0x0000000a -+run: ESP is now 0x00000064 ++run: incrementing ESP to 0x00000064 :(before "End Single-Byte Opcodes") case 0x58: @@ -269,9 +270,14 @@ case 0x5e: case 0x5f: { // pop stack into r32 uint8_t reg = op & 0x7; trace(2, "run") << "pop into reg " << NUM(reg) << end(); - Reg[reg].u = *reinterpret_cast(&Mem.at(Reg[ESP].u)); - trace(2, "run") << "popping value 0x" << HEXWORD << Reg[reg].u << end(); - Reg[ESP].u += 4; - trace(2, "run") << "ESP is now 0x" << HEXWORD << Reg[ESP].u << end(); + Reg[reg].u = pop(); break; } +:(code) +uint32_t pop() { + uint32_t result = *reinterpret_cast(&Mem.at(Reg[ESP].u)); + trace(2, "run") << "popping value 0x" << HEXWORD << result << end(); + Reg[ESP].u += 4; + trace(2, "run") << "incrementing ESP to 0x" << HEXWORD << Reg[ESP].u << end(); + return result; +} diff --git a/subx/012indirect_addressing.cc b/subx/012indirect_addressing.cc index 37d82a3f..f4e8c665 100644 --- a/subx/012indirect_addressing.cc +++ b/subx/012indirect_addressing.cc @@ -349,18 +349,14 @@ case 0xff: { // jump to r/m32 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 ++run: decrementing ESP to 0x00000010 ++run: pushing value 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(&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(&Mem.at(Reg[ESP].u)) << end(); + push(*val); break; } @@ -374,8 +370,8 @@ case 6: { 8f 00 # pop stack into *EAX (reg 0) +run: pop into effective address +run: effective address is mem at address 0x60 (reg 0) -+run: storing 0x00000030 -+run: ESP is now 0x00000014 ++run: popping value 0x00000030 ++run: incrementing ESP to 0x00000014 :(before "End Single-Byte Opcodes") case 0x8f: { // pop stack into r/m32 @@ -385,10 +381,7 @@ case 0x8f: { // pop stack into r/m32 case 0: { trace(2, "run") << "pop into effective address" << end(); int32_t* dest = effective_address(modrm); - *dest = *reinterpret_cast(&Mem.at(Reg[ESP].u)); - trace(2, "run") << "storing 0x" << HEXWORD << *dest << end(); - Reg[ESP].u += 4; - trace(2, "run") << "ESP is now 0x" << HEXWORD << Reg[ESP].u << end(); + *dest = pop(); break; } }