diff --git a/html/subx/011direct_addressing.cc.html b/html/subx/011direct_addressing.cc.html index 67117464..b8d9a853 100644 --- a/html/subx/011direct_addressing.cc.html +++ b/html/subx/011direct_addressing.cc.html @@ -214,7 +214,7 @@ if ('onhashchange' in window) { 149 break; 150 } 151 -152 //:: compare +152 //:: compare (cmp) 153 154 :(scenario compare_r32_with_r32_greater) 155 % Reg[0].i = 0x0a0b0c0d; @@ -258,6 +258,27 @@ if ('onhashchange' in window) { 193 +run: compare reg 3 with effective address 194 +run: effective address is reg 0 195 +run: SF=0; ZF=1; OF=0 +196 +197 //:: copy (mov) +198 +199 :(scenario copy_r32_to_r32) +200 % Reg[3].i = 0xaf; +201 # op ModRM SIB displacement immediate +202 89 d8 # copy EBX (reg 3) to EAX (reg 0) +203 +run: copy reg 3 to effective address +204 +run: effective address is reg 0 +205 +run: storing 0x000000af +206 +207 :(before "End Single-Byte Opcodes") +208 case 0x89: { // copy r32 to r/m32 +209 uint8_t modrm = next(); +210 uint8_t reg2 = (modrm>>3)&0x7; +211 trace(2, "run") << "copy reg " << NUM(reg2) << " to effective address" << end(); +212 int32_t* arg1 = effective_address(modrm); +213 *arg1 = Reg[reg2].i; +214 trace(2, "run") << "storing 0x" << HEXWORD << *arg1 << end(); +215 break; +216 } diff --git a/html/subx/012indirect_addressing.cc.html b/html/subx/012indirect_addressing.cc.html index ab3650f6..b43a2098 100644 --- a/html/subx/012indirect_addressing.cc.html +++ b/html/subx/012indirect_addressing.cc.html @@ -257,7 +257,7 @@ if ('onhashchange' in window) { 193 +run: effective address is mem at address 0x60 (reg 3) 194 +run: storing 0xf0f0ff00 195 -196 //:: compare +196 //:: compare (cmp) 197 198 :(scenario compare_mem_at_r32_with_r32_greater) 199 % Reg[0].i = 0x60; @@ -336,6 +336,39 @@ if ('onhashchange' in window) { 272 +run: compare effective address with reg 3 273 +run: effective address is mem at address 0x60 (reg 0) 274 +run: SF=0; ZF=1; OF=0 +275 +276 //:: copy (mov) +277 +278 :(scenario copy_r32_to_mem_at_r32) +279 % Reg[3].i = 0xaf; +280 % Reg[0].i = 0x60; +281 # op ModRM SIB displacement immediate +282 89 18 # copy EBX (reg 3) to *EAX (reg 0) +283 +run: copy reg 3 to effective address +284 +run: effective address is mem at address 0x60 (reg 0) +285 +run: storing 0x000000af +286 +287 //: +288 +289 :(scenario copy_mem_at_r32_to_r32) +290 % Reg[0].i = 0x60; +291 % SET_WORD_IN_MEM(0x60, 0x000000af); +292 # op ModRM SIB displacement immediate +293 8b 18 # copy *EAX (reg 0) to EBX (reg 3) +294 +run: copy effective address to reg 3 +295 +run: effective address is mem at address 0x60 (reg 0) +296 +run: storing 0x000000af +297 +298 :(before "End Single-Byte Opcodes") +299 case 0x8b: { // copy r32 to r/m32 +300 uint8_t modrm = next(); +301 uint8_t reg1 = (modrm>>3)&0x7; +302 trace(2, "run") << "copy effective address to reg " << NUM(reg1) << end(); +303 int32_t* arg2 = effective_address(modrm); +304 Reg[reg1].i = *arg2; +305 trace(2, "run") << "storing 0x" << HEXWORD << *arg2 << end(); +306 break; +307 } diff --git a/html/subx/013immediate_addressing.cc.html b/html/subx/013immediate_addressing.cc.html index 50164e5e..f7bb47f4 100644 --- a/html/subx/013immediate_addressing.cc.html +++ b/html/subx/013immediate_addressing.cc.html @@ -293,7 +293,7 @@ if ('onhashchange' in window) { 229 break; 230 } 231 -232 //:: compare +232 //:: compare (cmp) 233 234 :(scenario compare_imm32_with_eax_greater) 235 % Reg[0].i = 0x0d0c0b0a; @@ -395,6 +395,41 @@ if ('onhashchange' in window) { 331 +run: combine imm32 0x0d0c0b0a with effective address 332 +run: effective address is mem at address 0x60 (reg 3) 333 +run: SF=0; ZF=1; OF=0 +334 +335 //:: copy (mov) +336 +337 :(scenario copy_imm32_to_r32) +338 # op ModRM SIB displacement immediate +339 b8 03 0a 0b 0c 0d # copy 0x0d0c0b0a to EBX (reg 3) +340 +run: copy imm32 0x0d0c0b0a to reg 3 +341 +342 :(before "End Single-Byte Opcodes") +343 case 0xb8: { // copy imm32 to r32 +344 uint8_t modrm = next(); +345 int32_t arg2 = imm32(); +346 uint8_t reg1 = modrm&0x7; // ignore mod bits +347 trace(2, "run") << "copy imm32 0x" << HEXWORD << arg2 << " to reg " << NUM(reg1) << end(); +348 Reg[reg1].i = arg2; +349 break; +350 } +351 +352 //: +353 :(scenario copy_imm32_to_mem_at_r32) +354 % Reg[3].i = 0x60; +355 # op ModRM SIB displacement immediate +356 c7 03 0a 0b 0c 0d # copy 0x0d0c0b0a to *EBX (reg 3) +357 +run: copy imm32 0x0d0c0b0a to effective address +358 +run: effective address is mem at address 0x60 (reg 3) +359 +360 :(before "End Single-Byte Opcodes") +361 case 0xc7: { // copy imm32 to r32 +362 uint8_t modrm = next(); +363 int32_t arg2 = imm32(); +364 trace(2, "run") << "copy imm32 0x" << HEXWORD << arg2 << " to effective address" << end(); +365 int32_t* arg1 = effective_address(modrm); +366 *arg1 = arg2; +367 break; +368 } diff --git a/subx/011direct_addressing.cc b/subx/011direct_addressing.cc index a12b5541..f474ac99 100644 --- a/subx/011direct_addressing.cc +++ b/subx/011direct_addressing.cc @@ -149,7 +149,7 @@ case 0xf7: { // xor r32 with r/m32 break; } -//:: compare +//:: compare (cmp) :(scenario compare_r32_with_r32_greater) % Reg[0].i = 0x0a0b0c0d; @@ -193,3 +193,24 @@ case 0x39: { // set SF if r/m32 < r32 +run: compare reg 3 with effective address +run: effective address is reg 0 +run: SF=0; ZF=1; OF=0 + +//:: copy (mov) + +:(scenario copy_r32_to_r32) +% Reg[3].i = 0xaf; +# op ModRM SIB displacement immediate + 89 d8 # copy EBX (reg 3) to EAX (reg 0) ++run: copy reg 3 to effective address ++run: effective address is reg 0 ++run: storing 0x000000af + +:(before "End Single-Byte Opcodes") +case 0x89: { // copy r32 to r/m32 + uint8_t modrm = next(); + uint8_t reg2 = (modrm>>3)&0x7; + trace(2, "run") << "copy reg " << NUM(reg2) << " to effective address" << end(); + int32_t* arg1 = effective_address(modrm); + *arg1 = Reg[reg2].i; + trace(2, "run") << "storing 0x" << HEXWORD << *arg1 << end(); + break; +} diff --git a/subx/012indirect_addressing.cc b/subx/012indirect_addressing.cc index 546df707..3b2944b2 100644 --- a/subx/012indirect_addressing.cc +++ b/subx/012indirect_addressing.cc @@ -193,7 +193,7 @@ case 0x33: { // xor r/m32 with r32 +run: effective address is mem at address 0x60 (reg 3) +run: storing 0xf0f0ff00 -//:: compare +//:: compare (cmp) :(scenario compare_mem_at_r32_with_r32_greater) % Reg[0].i = 0x60; @@ -272,3 +272,36 @@ case 0x3b: { // set SF if r32 < r/m32 +run: compare effective address with reg 3 +run: effective address is mem at address 0x60 (reg 0) +run: SF=0; ZF=1; OF=0 + +//:: copy (mov) + +:(scenario copy_r32_to_mem_at_r32) +% Reg[3].i = 0xaf; +% Reg[0].i = 0x60; +# op ModRM SIB displacement immediate + 89 18 # copy EBX (reg 3) to *EAX (reg 0) ++run: copy reg 3 to effective address ++run: effective address is mem at address 0x60 (reg 0) ++run: storing 0x000000af + +//: + +:(scenario copy_mem_at_r32_to_r32) +% Reg[0].i = 0x60; +% SET_WORD_IN_MEM(0x60, 0x000000af); +# op ModRM SIB displacement immediate + 8b 18 # copy *EAX (reg 0) to EBX (reg 3) ++run: copy effective address to reg 3 ++run: effective address is mem at address 0x60 (reg 0) ++run: storing 0x000000af + +:(before "End Single-Byte Opcodes") +case 0x8b: { // copy r32 to r/m32 + uint8_t modrm = next(); + uint8_t reg1 = (modrm>>3)&0x7; + trace(2, "run") << "copy effective address to reg " << NUM(reg1) << end(); + int32_t* arg2 = effective_address(modrm); + Reg[reg1].i = *arg2; + trace(2, "run") << "storing 0x" << HEXWORD << *arg2 << end(); + break; +} diff --git a/subx/013immediate_addressing.cc b/subx/013immediate_addressing.cc index c370217a..dd1ce4c0 100644 --- a/subx/013immediate_addressing.cc +++ b/subx/013immediate_addressing.cc @@ -229,7 +229,7 @@ case 6: { break; } -//:: compare +//:: compare (cmp) :(scenario compare_imm32_with_eax_greater) % Reg[0].i = 0x0d0c0b0a; @@ -331,3 +331,38 @@ case 7: { +run: combine imm32 0x0d0c0b0a with effective address +run: effective address is mem at address 0x60 (reg 3) +run: SF=0; ZF=1; OF=0 + +//:: copy (mov) + +:(scenario copy_imm32_to_r32) +# op ModRM SIB displacement immediate + b8 03 0a 0b 0c 0d # copy 0x0d0c0b0a to EBX (reg 3) ++run: copy imm32 0x0d0c0b0a to reg 3 + +:(before "End Single-Byte Opcodes") +case 0xb8: { // copy imm32 to r32 + uint8_t modrm = next(); + int32_t arg2 = imm32(); + uint8_t reg1 = modrm&0x7; // ignore mod bits + trace(2, "run") << "copy imm32 0x" << HEXWORD << arg2 << " to reg " << NUM(reg1) << end(); + Reg[reg1].i = arg2; + break; +} + +//: +:(scenario copy_imm32_to_mem_at_r32) +% Reg[3].i = 0x60; +# op ModRM SIB displacement immediate + c7 03 0a 0b 0c 0d # copy 0x0d0c0b0a to *EBX (reg 3) ++run: copy imm32 0x0d0c0b0a to effective address ++run: effective address is mem at address 0x60 (reg 3) + +:(before "End Single-Byte Opcodes") +case 0xc7: { // copy imm32 to r32 + uint8_t modrm = next(); + int32_t arg2 = imm32(); + trace(2, "run") << "copy imm32 0x" << HEXWORD << arg2 << " to effective address" << end(); + int32_t* arg1 = effective_address(modrm); + *arg1 = arg2; + break; +}