From 0cb3c774b207c8a94bf9f9775e99e7d593d1e4fe Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Sat, 14 Oct 2017 19:18:34 -0700 Subject: 4064 --- html/subx/012indirect_addressing.cc.html | 393 +++++++++++++++---------------- 1 file changed, 187 insertions(+), 206 deletions(-) (limited to 'html/subx/012indirect_addressing.cc.html') diff --git a/html/subx/012indirect_addressing.cc.html b/html/subx/012indirect_addressing.cc.html index 863b554d..c6b76529 100644 --- a/html/subx/012indirect_addressing.cc.html +++ b/html/subx/012indirect_addressing.cc.html @@ -67,214 +67,195 @@ if ('onhashchange' in window) { 3 :(scenario add_r32_to_mem_at_r32) 4 % Reg[3].i = 0x10; 5 % Reg[0].i = 0x60; - 6 # word in addresses 0x60-0x63 has value 1 - 7 % Mem.at(0x60) = 1; - 8 # op ModR/M SIB displacement immediate - 9 01 18 # add EBX (reg 3) to *EAX (reg 0) - 10 +run: add reg 3 to effective address - 11 +run: effective address is mem at address 0x60 (reg 0) - 12 +run: storing 0x00000011 - 13 - 14 :(before "End Mod Special-cases") - 15 case 0: - 16 // mod 0 is usually indirect addressing - 17 switch (rm) { - 18 default: - 19 ¦ trace(2, "run") << "effective address is mem at address 0x" << std::hex << Reg[rm].u << " (reg " << NUM(rm) << ")" << end(); - 20 ¦ assert(Reg[rm].u + sizeof(int32_t) <= Mem.size()); - 21 ¦ result = reinterpret_cast<int32_t*>(&Mem.at(Reg[rm].u)); // rely on the host itself being in little-endian order - 22 ¦ break; - 23 // End Mod 0 Special-cases - 24 } - 25 break; - 26 - 27 //: - 28 - 29 :(scenario add_mem_at_r32_to_r32) - 30 % Reg[0].i = 0x60; - 31 % Reg[3].i = 0x10; - 32 % Mem.at(0x60) = 1; - 33 # op ModR/M SIB displacement immediate - 34 03 18 # add *EAX (reg 0) to EBX (reg 3) - 35 +run: add effective address to reg 3 - 36 +run: effective address is mem at address 0x60 (reg 0) - 37 +run: storing 0x00000011 - 38 - 39 :(before "End Single-Byte Opcodes") - 40 case 0x03: { // add r/m32 to r32 - 41 uint8_t modrm = next(); - 42 uint8_t arg1 = (modrm>>3)&0x7; - 43 trace(2, "run") << "add effective address to reg " << NUM(arg1) << end(); - 44 const int32_t* arg2 = effective_address(modrm); - 45 BINARY_ARITHMETIC_OP(+, Reg[arg1].i, *arg2); - 46 break; - 47 } - 48 - 49 //:: subtract - 50 - 51 :(scenario subtract_r32_from_mem_at_r32) - 52 % Reg[0].i = 0x60; - 53 % Mem.at(0x60) = 10; - 54 % Reg[3].i = 1; - 55 # op ModRM SIB displacement immediate - 56 29 18 # subtract EBX (reg 3) from *EAX (reg 0) - 57 +run: subtract reg 3 from effective address - 58 +run: effective address is mem at address 0x60 (reg 0) - 59 +run: storing 0x00000009 - 60 - 61 //: - 62 - 63 :(scenario subtract_mem_at_r32_from_r32) - 64 % Reg[0].i = 0x60; - 65 % Mem.at(0x60) = 1; - 66 % Reg[3].i = 10; - 67 # op ModRM SIB displacement immediate - 68 2b 18 # subtract *EAX (reg 0) from EBX (reg 3) - 69 +run: subtract effective address from reg 3 - 70 +run: effective address is mem at address 0x60 (reg 0) - 71 +run: storing 0x00000009 - 72 - 73 :(before "End Single-Byte Opcodes") - 74 case 0x2b: { // subtract r/m32 from r32 - 75 uint8_t modrm = next(); - 76 uint8_t arg1 = (modrm>>3)&0x7; - 77 trace(2, "run") << "subtract effective address from reg " << NUM(arg1) << end(); - 78 const int32_t* arg2 = effective_address(modrm); - 79 BINARY_ARITHMETIC_OP(-, Reg[arg1].i, *arg2); - 80 break; - 81 } - 82 - 83 //:: and - 84 - 85 :(scenario and_r32_with_mem_at_r32) - 86 % Reg[0].i = 0x60; - 87 % Mem.at(0x60) = 0x0d; - 88 % Mem.at(0x61) = 0x0c; - 89 % Mem.at(0x62) = 0x0b; - 90 % Mem.at(0x63) = 0x0a; - 91 % Reg[3].i = 0xff; - 92 # op ModRM SIB displacement immediate - 93 21 18 # and EBX (reg 3) with *EAX (reg 0) - 94 +run: and reg 3 with effective address - 95 +run: effective address is mem at address 0x60 (reg 0) - 96 +run: storing 0x0000000d - 97 - 98 //: - 99 -100 :(scenario and_mem_at_r32_with_r32) -101 % Reg[0].i = 0x60; -102 % Mem.at(0x60) = 0xff; -103 % Reg[3].i = 0x0a0b0c0d; -104 # op ModRM SIB displacement immediate -105 23 18 # and *EAX (reg 0) with EBX (reg 3) -106 +run: and effective address with reg 3 -107 +run: effective address is mem at address 0x60 (reg 0) -108 +run: storing 0x0000000d -109 -110 :(before "End Single-Byte Opcodes") -111 case 0x23: { // and r/m32 with r32 -112 uint8_t modrm = next(); -113 uint8_t arg1 = (modrm>>3)&0x7; -114 trace(2, "run") << "and effective address with reg " << NUM(arg1) << end(); -115 const int32_t* arg2 = effective_address(modrm); -116 BINARY_BITWISE_OP(&, Reg[arg1].u, *arg2); -117 break; -118 } -119 -120 //:: or -121 -122 :(scenario or_r32_with_mem_at_r32) -123 % Reg[0].i = 0x60; -124 % Mem.at(0x60) = 0x0d; -125 % Mem.at(0x61) = 0x0c; -126 % Mem.at(0x62) = 0x0b; -127 % Mem.at(0x63) = 0x0a; -128 % Reg[3].i = 0xa0b0c0d0; -129 # op ModRM SIB displacement immediate -130 09 18 # or EBX (reg 3) with *EAX (reg 0) -131 +run: or reg 3 with effective address -132 +run: effective address is mem at address 0x60 (reg 0) -133 +run: storing 0xaabbccdd -134 -135 //: -136 -137 :(scenario or_mem_at_r32_with_r32) -138 % Reg[0].i = 0x60; -139 % Mem.at(0x60) = 0x0d; -140 % Mem.at(0x61) = 0x0c; -141 % Mem.at(0x62) = 0x0b; -142 % Mem.at(0x63) = 0x0a; -143 % Reg[3].i = 0xa0b0c0d0; -144 # op ModRM SIB displacement immediate -145 0b 18 # or *EAX (reg 0) with EBX (reg 3) -146 +run: or effective address with reg 3 -147 +run: effective address is mem at address 0x60 (reg 0) -148 +run: storing 0xaabbccdd + 6 % SET_WORD_IN_MEM(0x60, 1); + 7 # op ModR/M SIB displacement immediate + 8 01 18 # add EBX (reg 3) to *EAX (reg 0) + 9 +run: add reg 3 to effective address + 10 +run: effective address is mem at address 0x60 (reg 0) + 11 +run: storing 0x00000011 + 12 + 13 :(before "End Mod Special-cases") + 14 case 0: + 15 // mod 0 is usually indirect addressing + 16 switch (rm) { + 17 default: + 18 ¦ trace(2, "run") << "effective address is mem at address 0x" << std::hex << Reg[rm].u << " (reg " << NUM(rm) << ")" << end(); + 19 ¦ assert(Reg[rm].u + sizeof(int32_t) <= Mem.size()); + 20 ¦ result = reinterpret_cast<int32_t*>(&Mem.at(Reg[rm].u)); // rely on the host itself being in little-endian order + 21 ¦ break; + 22 // End Mod 0 Special-cases + 23 } + 24 break; + 25 + 26 //: + 27 + 28 :(scenario add_mem_at_r32_to_r32) + 29 % Reg[0].i = 0x60; + 30 % Reg[3].i = 0x10; + 31 % SET_WORD_IN_MEM(0x60, 1); + 32 # op ModR/M SIB displacement immediate + 33 03 18 # add *EAX (reg 0) to EBX (reg 3) + 34 +run: add effective address to reg 3 + 35 +run: effective address is mem at address 0x60 (reg 0) + 36 +run: storing 0x00000011 + 37 + 38 :(before "End Single-Byte Opcodes") + 39 case 0x03: { // add r/m32 to r32 + 40 uint8_t modrm = next(); + 41 uint8_t arg1 = (modrm>>3)&0x7; + 42 trace(2, "run") << "add effective address to reg " << NUM(arg1) << end(); + 43 const int32_t* arg2 = effective_address(modrm); + 44 BINARY_ARITHMETIC_OP(+, Reg[arg1].i, *arg2); + 45 break; + 46 } + 47 + 48 //:: subtract + 49 + 50 :(scenario subtract_r32_from_mem_at_r32) + 51 % Reg[0].i = 0x60; + 52 % SET_WORD_IN_MEM(0x60, 10); + 53 % Reg[3].i = 1; + 54 # op ModRM SIB displacement immediate + 55 29 18 # subtract EBX (reg 3) from *EAX (reg 0) + 56 +run: subtract reg 3 from effective address + 57 +run: effective address is mem at address 0x60 (reg 0) + 58 +run: storing 0x00000009 + 59 + 60 //: + 61 + 62 :(scenario subtract_mem_at_r32_from_r32) + 63 % Reg[0].i = 0x60; + 64 % SET_WORD_IN_MEM(0x60, 1); + 65 % Reg[3].i = 10; + 66 # op ModRM SIB displacement immediate + 67 2b 18 # subtract *EAX (reg 0) from EBX (reg 3) + 68 +run: subtract effective address from reg 3 + 69 +run: effective address is mem at address 0x60 (reg 0) + 70 +run: storing 0x00000009 + 71 + 72 :(before "End Single-Byte Opcodes") + 73 case 0x2b: { // subtract r/m32 from r32 + 74 uint8_t modrm = next(); + 75 uint8_t arg1 = (modrm>>3)&0x7; + 76 trace(2, "run") << "subtract effective address from reg " << NUM(arg1) << end(); + 77 const int32_t* arg2 = effective_address(modrm); + 78 BINARY_ARITHMETIC_OP(-, Reg[arg1].i, *arg2); + 79 break; + 80 } + 81 + 82 //:: and + 83 + 84 :(scenario and_r32_with_mem_at_r32) + 85 % Reg[0].i = 0x60; + 86 % SET_WORD_IN_MEM(0x60, 0x0a0b0c0d); + 87 % Reg[3].i = 0xff; + 88 # op ModRM SIB displacement immediate + 89 21 18 # and EBX (reg 3) with *EAX (reg 0) + 90 +run: and reg 3 with effective address + 91 +run: effective address is mem at address 0x60 (reg 0) + 92 +run: storing 0x0000000d + 93 + 94 //: + 95 + 96 :(scenario and_mem_at_r32_with_r32) + 97 % Reg[0].i = 0x60; + 98 % SET_WORD_IN_MEM(0x60, 0x000000ff); + 99 % Reg[3].i = 0x0a0b0c0d; +100 # op ModRM SIB displacement immediate +101 23 18 # and *EAX (reg 0) with EBX (reg 3) +102 +run: and effective address with reg 3 +103 +run: effective address is mem at address 0x60 (reg 0) +104 +run: storing 0x0000000d +105 +106 :(before "End Single-Byte Opcodes") +107 case 0x23: { // and r/m32 with r32 +108 uint8_t modrm = next(); +109 uint8_t arg1 = (modrm>>3)&0x7; +110 trace(2, "run") << "and effective address with reg " << NUM(arg1) << end(); +111 const int32_t* arg2 = effective_address(modrm); +112 BINARY_BITWISE_OP(&, Reg[arg1].u, *arg2); +113 break; +114 } +115 +116 //:: or +117 +118 :(scenario or_r32_with_mem_at_r32) +119 % Reg[0].i = 0x60; +120 % SET_WORD_IN_MEM(0x60, 0x0a0b0c0d); +121 % Reg[3].i = 0xa0b0c0d0; +122 # op ModRM SIB displacement immediate +123 09 18 # or EBX (reg 3) with *EAX (reg 0) +124 +run: or reg 3 with effective address +125 +run: effective address is mem at address 0x60 (reg 0) +126 +run: storing 0xaabbccdd +127 +128 //: +129 +130 :(scenario or_mem_at_r32_with_r32) +131 % Reg[0].i = 0x60; +132 % SET_WORD_IN_MEM(0x60, 0x0a0b0c0d); +133 % Reg[3].i = 0xa0b0c0d0; +134 # op ModRM SIB displacement immediate +135 0b 18 # or *EAX (reg 0) with EBX (reg 3) +136 +run: or effective address with reg 3 +137 +run: effective address is mem at address 0x60 (reg 0) +138 +run: storing 0xaabbccdd +139 +140 :(before "End Single-Byte Opcodes") +141 case 0x0b: { // or r/m32 with r32 +142 uint8_t modrm = next(); +143 uint8_t arg1 = (modrm>>3)&0x7; +144 trace(2, "run") << "or effective address with reg " << NUM(arg1) << end(); +145 const int32_t* arg2 = effective_address(modrm); +146 BINARY_BITWISE_OP(|, Reg[arg1].u, *arg2); +147 break; +148 } 149 -150 :(before "End Single-Byte Opcodes") -151 case 0x0b: { // or r/m32 with r32 -152 uint8_t modrm = next(); -153 uint8_t arg1 = (modrm>>3)&0x7; -154 trace(2, "run") << "or effective address with reg " << NUM(arg1) << end(); -155 const int32_t* arg2 = effective_address(modrm); -156 BINARY_BITWISE_OP(|, Reg[arg1].u, *arg2); -157 break; -158 } -159 -160 //:: xor +150 //:: xor +151 +152 :(scenario xor_r32_with_mem_at_r32) +153 % Reg[0].i = 0x60; +154 % SET_WORD_IN_MEM(0x60, 0xaabb0c0d); +155 % Reg[3].i = 0xa0b0c0d0; +156 # op ModRM SIB displacement immediate +157 31 18 # xor EBX (reg 3) with *EAX (reg 0) +158 +run: xor reg 3 with effective address +159 +run: effective address is mem at address 0x60 (reg 0) +160 +run: storing 0x0a0bccdd 161 -162 :(scenario xor_r32_with_mem_at_r32) -163 % Reg[0].i = 0x60; -164 % Mem.at(0x60) = 0x0d; -165 % Mem.at(0x61) = 0x0c; -166 % Mem.at(0x62) = 0xbb; -167 % Mem.at(0x63) = 0xaa; -168 % Reg[3].i = 0xa0b0c0d0; -169 # op ModRM SIB displacement immediate -170 31 18 # xor EBX (reg 3) with *EAX (reg 0) -171 +run: xor reg 3 with effective address -172 +run: effective address is mem at address 0x60 (reg 0) -173 +run: storing 0x0a0bccdd -174 -175 //: -176 -177 :(scenario xor_mem_at_r32_with_r32) -178 % Reg[0].i = 0x60; -179 % Mem.at(0x60) = 0x0d; -180 % Mem.at(0x61) = 0x0c; -181 % Mem.at(0x62) = 0x0b; -182 % Mem.at(0x63) = 0x0a; -183 % Reg[3].i = 0xa0b0c0d0; -184 # op ModRM SIB displacement immediate -185 33 18 # xor *EAX (reg 0) with EBX (reg 3) -186 +run: xor effective address with reg 3 -187 +run: effective address is mem at address 0x60 (reg 0) -188 +run: storing 0xaabbccdd -189 -190 :(before "End Single-Byte Opcodes") -191 case 0x33: { // xor r/m32 with r32 -192 uint8_t modrm = next(); -193 uint8_t arg1 = (modrm>>3)&0x7; -194 trace(2, "run") << "xor effective address with reg " << NUM(arg1) << end(); -195 const int32_t* arg2 = effective_address(modrm); -196 BINARY_BITWISE_OP(|, Reg[arg1].u, *arg2); -197 break; -198 } -199 -200 //:: not -201 -202 :(scenario not_r32_with_mem_at_r32) -203 % Reg[3].i = 0x60; -204 # word at 0x60 is 0x0f0f00ff -205 % Mem.at(0x60) = 0xff; -206 % Mem.at(0x61) = 0x00; -207 % Mem.at(0x62) = 0x0f; -208 % Mem.at(0x63) = 0x0f; -209 # op ModRM SIB displacement immediate -210 f7 03 # negate *EBX (reg 3) -211 +run: 'not' of effective address -212 +run: effective address is mem at address 0x60 (reg 3) -213 +run: storing 0xf0f0ff00 +162 //: +163 +164 :(scenario xor_mem_at_r32_with_r32) +165 % Reg[0].i = 0x60; +166 % SET_WORD_IN_MEM(0x60, 0x0a0b0c0d); +167 % Reg[3].i = 0xa0b0c0d0; +168 # op ModRM SIB displacement immediate +169 33 18 # xor *EAX (reg 0) with EBX (reg 3) +170 +run: xor effective address with reg 3 +171 +run: effective address is mem at address 0x60 (reg 0) +172 +run: storing 0xaabbccdd +173 +174 :(before "End Single-Byte Opcodes") +175 case 0x33: { // xor r/m32 with r32 +176 uint8_t modrm = next(); +177 uint8_t arg1 = (modrm>>3)&0x7; +178 trace(2, "run") << "xor effective address with reg " << NUM(arg1) << end(); +179 const int32_t* arg2 = effective_address(modrm); +180 BINARY_BITWISE_OP(|, Reg[arg1].u, *arg2); +181 break; +182 } +183 +184 //:: not +185 +186 :(scenario not_r32_with_mem_at_r32) +187 % Reg[3].i = 0x60; +188 # word at 0x60 is 0x0f0f00ff +189 % SET_WORD_IN_MEM(0x60, 0x0f0f00ff); +190 # op ModRM SIB displacement immediate +191 f7 03 # negate *EBX (reg 3) +192 +run: 'not' of effective address +193 +run: effective address is mem at address 0x60 (reg 3) +194 +run: storing 0xf0f0ff00 -- cgit 1.4.1-2-gfad0