From d3a9db3aff54ea485f409eaaef3d8f56ad77f0dc Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Mon, 5 Oct 2020 11:00:05 -0700 Subject: 6958 --- html/021byte_addressing.cc.html | 166 ++++++++++++++++++++-------------------- 1 file changed, 83 insertions(+), 83 deletions(-) (limited to 'html/021byte_addressing.cc.html') diff --git a/html/021byte_addressing.cc.html b/html/021byte_addressing.cc.html index 21d009cc..2da9c622 100644 --- a/html/021byte_addressing.cc.html +++ b/html/021byte_addressing.cc.html @@ -15,14 +15,14 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color: a { color:inherit; } * { font-size:12pt; font-size: 1em; } .LineNr { } +.SpecialChar { color: #d70000; } .Constant { color: #008787; } .Comment { color: #005faf; } .Delimiter { color: #c000c0; } -.Special { color: #d70000; } .Identifier { color: #af5f00; } .Normal { color: #000000; background-color: #c6c6c6; padding-bottom: 1px; } -.SalientComment { color: #0000af; } .cSpecial { color: #008000; } +.SalientComment { color: #0000af; } --> @@ -74,7 +74,7 @@ if ('onhashchange' in window) { 14 case 5: return "CH"; // second lowest byte of ECX 15 case 6: return "DH"; // second lowest byte of EDX 16 case 7: return "BH"; // second lowest byte of EBX - 17 default: raise << "invalid 8-bit register " << r << '\n' << end(); return ""; + 17 default: raise << "invalid 8-bit register " << r << '\n' << end(); return ""; 18 } 19 } 20 @@ -83,27 +83,27 @@ if ('onhashchange' in window) { 23 uint8_t rm = modrm & 0x7; 24 if (mod == 3) { 25 // select an 8-bit register - 26 trace(Callstack_depth+1, "run") << "r/m8 is " << rname_8bit(rm) << end(); + 26 trace(Callstack_depth+1, "run") << "r/m8 is " << rname_8bit(rm) << end(); 27 return reg_8bit(rm); 28 } 29 // the rest is as usual - 30 return mem_addr_u8(effective_address_number(modrm)); + 30 return mem_addr_u8(effective_address_number(modrm)); 31 } 32 33 uint8_t* reg_8bit(uint8_t rm) { - 34 uint8_t* result = reinterpret_cast<uint8_t*>(&Reg[rm & 0x3].i); // _L register + 34 uint8_t* result = reinterpret_cast<uint8_t*>(&Reg[rm & 0x3].i); // _L register 35 if (rm & 0x4) 36 ++result; // _H register; assumes host is little-endian 37 return result; 38 } 39 40 :(before "End Initialize Op Names") - 41 put_new(Name, "88", "copy r8 to r8/m8-at-r32"); + 41 put_new(Name, "88", "copy r8 to r8/m8-at-r32"); 42 43 :(code) 44 void test_copy_r8_to_mem_at_r32() { - 45 Reg[EBX].i = 0x224488ab; - 46 Reg[EAX].i = 0x2000; + 45 Reg[EBX].i = 0x224488ab; + 46 Reg[EAX].i = 0x2000; 47 run( 48 "== code 0x1\n" 49 // op ModR/M SIB displacement immediate @@ -112,36 +112,36 @@ if ('onhashchange' in window) { 52 "== data 0x2000\n" 53 "f0 cc bb aa\n" 54 ); - 55 CHECK_TRACE_CONTENTS( + 55 CHECK_TRACE_CONTENTS( 56 "run: copy BL to r8/m8-at-r32\n" 57 "run: effective address is 0x00002000 (EAX)\n" 58 "run: storing 0xab\n" 59 ); - 60 CHECK_EQ(0xaabbccab, read_mem_u32(0x2000)); + 60 CHECK_EQ(0xaabbccab, read_mem_u32(0x2000)); 61 } 62 63 :(before "End Single-Byte Opcodes") 64 case 0x88: { // copy r8 to r/m8 - 65 const uint8_t modrm = next(); + 65 const uint8_t modrm = next(); 66 const uint8_t rsrc = (modrm>>3)&0x7; - 67 trace(Callstack_depth+1, "run") << "copy " << rname_8bit(rsrc) << " to r8/m8-at-r32" << end(); + 67 trace(Callstack_depth+1, "run") << "copy " << rname_8bit(rsrc) << " to r8/m8-at-r32" << end(); 68 // use unsigned to zero-extend 8-bit value to 32 bits 69 uint8_t* dest = effective_byte_address(modrm); 70 const uint8_t* src = reg_8bit(rsrc); 71 *dest = *src; // Read/write multiple elements of vector<uint8_t> at once. Assumes sizeof(int) == 4 on the host as well. - 72 trace(Callstack_depth+1, "run") << "storing 0x" << HEXBYTE << NUM(*dest) << end(); + 72 trace(Callstack_depth+1, "run") << "storing 0x" << HEXBYTE << NUM(*dest) << end(); 73 break; 74 } 75 76 //: 77 78 :(before "End Initialize Op Names") - 79 put_new(Name, "8a", "copy r8/m8-at-r32 to r8"); + 79 put_new(Name, "8a", "copy r8/m8-at-r32 to r8"); 80 81 :(code) 82 void test_copy_mem_at_r32_to_r8() { - 83 Reg[EBX].i = 0xaabbcc0f; // one nibble each of lowest byte set to all 0s and all 1s, to maximize value of this test - 84 Reg[EAX].i = 0x2000; + 83 Reg[EBX].i = 0xaabbcc0f; // one nibble each of lowest byte set to all 0s and all 1s, to maximize value of this test + 84 Reg[EAX].i = 0x2000; 85 run( 86 "== code 0x1\n" 87 // op ModR/M SIB displacement immediate @@ -150,7 +150,7 @@ if ('onhashchange' in window) { 90 "== data 0x2000\n" 91 "ab ff ff ff\n" // 0xab with more data in following bytes 92 ); - 93 CHECK_TRACE_CONTENTS( + 93 CHECK_TRACE_CONTENTS( 94 "run: copy r8/m8-at-r32 to BL\n" 95 "run: effective address is 0x00002000 (EAX)\n" 96 "run: storing 0xab\n" @@ -161,46 +161,46 @@ if ('onhashchange' in window) { 101 102 :(before "End Single-Byte Opcodes") 103 case 0x8a: { // copy r/m8 to r8 -104 const uint8_t modrm = next(); +104 const uint8_t modrm = next(); 105 const uint8_t rdest = (modrm>>3)&0x7; -106 trace(Callstack_depth+1, "run") << "copy r8/m8-at-r32 to " << rname_8bit(rdest) << end(); +106 trace(Callstack_depth+1, "run") << "copy r8/m8-at-r32 to " << rname_8bit(rdest) << end(); 107 // use unsigned to zero-extend 8-bit value to 32 bits 108 const uint8_t* src = effective_byte_address(modrm); 109 uint8_t* dest = reg_8bit(rdest); -110 trace(Callstack_depth+1, "run") << "storing 0x" << HEXBYTE << NUM(*src) << end(); +110 trace(Callstack_depth+1, "run") << "storing 0x" << HEXBYTE << NUM(*src) << end(); 111 *dest = *src; // Read/write multiple elements of vector<uint8_t> at once. Assumes sizeof(int) == 4 on the host as well. 112 const uint8_t rdest_32bit = rdest & 0x3; -113 trace(Callstack_depth+1, "run") << rname(rdest_32bit) << " now contains 0x" << HEXWORD << Reg[rdest_32bit].u << end(); +113 trace(Callstack_depth+1, "run") << rname(rdest_32bit) << " now contains 0x" << HEXWORD << Reg[rdest_32bit].u << end(); 114 break; 115 } 116 117 :(code) 118 void test_cannot_copy_byte_to_ESP_EBP_ESI_EDI() { -119 Reg[ESI].u = 0xaabbccdd; -120 Reg[EBX].u = 0x11223344; +119 Reg[ESI].u = 0xaabbccdd; +120 Reg[EBX].u = 0x11223344; 121 run( 122 "== code 0x1\n" 123 // op ModR/M SIB displacement immediate 124 " 8a f3 \n" // copy just the byte at *EBX to 8-bit register '6' 125 // ModR/M in binary: 11 (direct mode) 110 (dest 8-bit 'register 6') 011 (src EBX) 126 ); -127 CHECK_TRACE_CONTENTS( +127 CHECK_TRACE_CONTENTS( 128 // ensure 8-bit register '6' is DH, not ESI 129 "run: copy r8/m8-at-r32 to DH\n" 130 "run: storing 0x44\n" 131 ); 132 // ensure ESI is unchanged -133 CHECK_EQ(Reg[ESI].u, 0xaabbccdd); +133 CHECK_EQ(Reg[ESI].u, 0xaabbccdd); 134 } 135 136 //: 137 138 :(before "End Initialize Op Names") -139 put_new(Name, "c6", "copy imm8 to r8/m8-at-r32 (mov)"); +139 put_new(Name, "c6", "copy imm8 to r8/m8-at-r32 (mov)"); 140 141 :(code) 142 void test_copy_imm8_to_mem_at_r32() { -143 Reg[EAX].i = 0x2000; +143 Reg[EAX].i = 0x2000; 144 run( 145 "== code 0x1\n" 146 // op ModR/M SIB displacement immediate @@ -209,125 +209,125 @@ if ('onhashchange' in window) { 149 "== data 0x2000\n" 150 "f0 cc bb aa\n" 151 ); -152 CHECK_TRACE_CONTENTS( +152 CHECK_TRACE_CONTENTS( 153 "run: copy imm8 to r8/m8-at-r32\n" 154 "run: effective address is 0x00002000 (EAX)\n" 155 "run: storing 0xdd\n" 156 ); -157 CHECK_EQ(0xaabbccdd, read_mem_u32(0x2000)); +157 CHECK_EQ(0xaabbccdd, read_mem_u32(0x2000)); 158 } 159 160 :(before "End Single-Byte Opcodes") 161 case 0xc6: { // copy imm8 to r/m8 -162 const uint8_t modrm = next(); -163 const uint8_t src = next(); -164 trace(Callstack_depth+1, "run") << "copy imm8 to r8/m8-at-r32" << end(); -165 trace(Callstack_depth+1, "run") << "imm8 is 0x" << HEXWORD << NUM(src) << end(); +162 const uint8_t modrm = next(); +163 const uint8_t src = next(); +164 trace(Callstack_depth+1, "run") << "copy imm8 to r8/m8-at-r32" << end(); +165 trace(Callstack_depth+1, "run") << "imm8 is 0x" << HEXWORD << NUM(src) << end(); 166 const uint8_t subop = (modrm>>3)&0x7; // middle 3 'reg opcode' bits 167 if (subop != 0) { -168 cerr << "unrecognized subop for opcode c6: " << NUM(subop) << " (only 0/copy currently implemented)\n"; +168 cerr << "unrecognized subop for opcode c6: " << NUM(subop) << " (only 0/copy currently implemented)\n"; 169 exit(1); 170 } 171 // use unsigned to zero-extend 8-bit value to 32 bits 172 uint8_t* dest = effective_byte_address(modrm); 173 *dest = src; // Write multiple elements of vector<uint8_t> at once. Assumes sizeof(int) == 4 on the host as well. -174 trace(Callstack_depth+1, "run") << "storing 0x" << HEXBYTE << NUM(*dest) << end(); +174 trace(Callstack_depth+1, "run") << "storing 0x" << HEXBYTE << NUM(*dest) << end(); 175 break; 176 } 177 178 //:: set flags (setcc) 179 180 :(before "End Initialize Op Names") -181 put_new(Name_0f, "94", "set r8/m8-at-rm32 to 1 if equal, if ZF is set, 0 otherwise (setcc/setz/sete)"); -182 put_new(Name_0f, "95", "set r8/m8-at-rm32 to 1 if not equal, if ZF is not set, 0 otherwise (setcc/setnz/setne)"); -183 put_new(Name_0f, "9f", "set r8/m8-at-rm32 to 1 if greater (signed), if ZF is unset and SF == OF, 0 otherwise (setcc/setg/setnle)"); -184 put_new(Name_0f, "97", "set r8/m8-at-rm32 to 1 if greater (unsigned), if ZF is unset and CF is unset, 0 otherwise (setcc/seta/setnbe)"); -185 put_new(Name_0f, "9d", "set r8/m8-at-rm32 to 1 if greater or equal (signed), if SF == OF, 0 otherwise (setcc/setge/setnl)"); -186 put_new(Name_0f, "93", "set r8/m8-at-rm32 to 1 if greater or equal (unsigned), if CF is unset, 0 otherwise (setcc/setae/setnb)"); -187 put_new(Name_0f, "9c", "set r8/m8-at-rm32 to 1 if lesser (signed), if SF != OF, 0 otherwise (setcc/setl/setnge)"); -188 put_new(Name_0f, "92", "set r8/m8-at-rm32 to 1 if lesser (unsigned), if CF is set, 0 otherwise (setcc/setb/setnae)"); -189 put_new(Name_0f, "9e", "set r8/m8-at-rm32 to 1 if lesser or equal (signed), if ZF is set or SF != OF, 0 otherwise (setcc/setle/setng)"); -190 put_new(Name_0f, "96", "set r8/m8-at-rm32 to 1 if lesser or equal (unsigned), if ZF is set or CF is set, 0 otherwise (setcc/setbe/setna)"); +181 put_new(Name_0f, "94", "set r8/m8-at-rm32 to 1 if equal, if ZF is set, 0 otherwise (setcc/setz/sete)"); +182 put_new(Name_0f, "95", "set r8/m8-at-rm32 to 1 if not equal, if ZF is not set, 0 otherwise (setcc/setnz/setne)"); +183 put_new(Name_0f, "9f", "set r8/m8-at-rm32 to 1 if greater (signed), if ZF is unset and SF == OF, 0 otherwise (setcc/setg/setnle)"); +184 put_new(Name_0f, "97", "set r8/m8-at-rm32 to 1 if greater (unsigned), if ZF is unset and CF is unset, 0 otherwise (setcc/seta/setnbe)"); +185 put_new(Name_0f, "9d", "set r8/m8-at-rm32 to 1 if greater or equal (signed), if SF == OF, 0 otherwise (setcc/setge/setnl)"); +186 put_new(Name_0f, "93", "set r8/m8-at-rm32 to 1 if greater or equal (unsigned), if CF is unset, 0 otherwise (setcc/setae/setnb)"); +187 put_new(Name_0f, "9c", "set r8/m8-at-rm32 to 1 if lesser (signed), if SF != OF, 0 otherwise (setcc/setl/setnge)"); +188 put_new(Name_0f, "92", "set r8/m8-at-rm32 to 1 if lesser (unsigned), if CF is set, 0 otherwise (setcc/setb/setnae)"); +189 put_new(Name_0f, "9e", "set r8/m8-at-rm32 to 1 if lesser or equal (signed), if ZF is set or SF != OF, 0 otherwise (setcc/setle/setng)"); +190 put_new(Name_0f, "96", "set r8/m8-at-rm32 to 1 if lesser or equal (unsigned), if ZF is set or CF is set, 0 otherwise (setcc/setbe/setna)"); 191 192 :(before "End Two-Byte Opcodes Starting With 0f") 193 case 0x94: { // set r8/m8-at-rm32 if ZF -194 const uint8_t modrm = next(); -195 trace(Callstack_depth+1, "run") << "set r8/m8-at-rm32" << end(); +194 const uint8_t modrm = next(); +195 trace(Callstack_depth+1, "run") << "set r8/m8-at-rm32" << end(); 196 uint8_t* dest = effective_byte_address(modrm); -197 *dest = ZF; -198 trace(Callstack_depth+1, "run") << "storing " << NUM(*dest) << end(); +197 *dest = ZF; +198 trace(Callstack_depth+1, "run") << "storing " << NUM(*dest) << end(); 199 break; 200 } 201 case 0x95: { // set r8/m8-at-rm32 if !ZF -202 const uint8_t modrm = next(); -203 trace(Callstack_depth+1, "run") << "set r8/m8-at-rm32" << end(); +202 const uint8_t modrm = next(); +203 trace(Callstack_depth+1, "run") << "set r8/m8-at-rm32" << end(); 204 uint8_t* dest = effective_byte_address(modrm); 205 *dest = !ZF; -206 trace(Callstack_depth+1, "run") << "storing " << NUM(*dest) << end(); +206 trace(Callstack_depth+1, "run") << "storing " << NUM(*dest) << end(); 207 break; 208 } 209 case 0x9f: { // set r8/m8-at-rm32 if !SF and !ZF -210 const uint8_t modrm = next(); -211 trace(Callstack_depth+1, "run") << "set r8/m8-at-rm32" << end(); +210 const uint8_t modrm = next(); +211 trace(Callstack_depth+1, "run") << "set r8/m8-at-rm32" << end(); 212 uint8_t* dest = effective_byte_address(modrm); -213 *dest = !ZF && SF == OF; -214 trace(Callstack_depth+1, "run") << "storing " << NUM(*dest) << end(); +213 *dest = !ZF && SF == OF; +214 trace(Callstack_depth+1, "run") << "storing " << NUM(*dest) << end(); 215 break; 216 } 217 case 0x97: { // set r8/m8-at-rm32 if !CF and !ZF -218 const uint8_t modrm = next(); -219 trace(Callstack_depth+1, "run") << "set r8/m8-at-rm32" << end(); +218 const uint8_t modrm = next(); +219 trace(Callstack_depth+1, "run") << "set r8/m8-at-rm32" << end(); 220 uint8_t* dest = effective_byte_address(modrm); 221 *dest = (!CF && !ZF); -222 trace(Callstack_depth+1, "run") << "storing " << NUM(*dest) << end(); +222 trace(Callstack_depth+1, "run") << "storing " << NUM(*dest) << end(); 223 break; 224 } 225 case 0x9d: { // set r8/m8-at-rm32 if !SF -226 const uint8_t modrm = next(); -227 trace(Callstack_depth+1, "run") << "set r8/m8-at-rm32" << end(); +226 const uint8_t modrm = next(); +227 trace(Callstack_depth+1, "run") << "set r8/m8-at-rm32" << end(); 228 uint8_t* dest = effective_byte_address(modrm); -229 *dest = (SF == OF); -230 trace(Callstack_depth+1, "run") << "storing " << NUM(*dest) << end(); +229 *dest = (SF == OF); +230 trace(Callstack_depth+1, "run") << "storing " << NUM(*dest) << end(); 231 break; 232 } 233 case 0x93: { // set r8/m8-at-rm32 if !CF -234 const uint8_t modrm = next(); -235 trace(Callstack_depth+1, "run") << "set r8/m8-at-rm32" << end(); +234 const uint8_t modrm = next(); +235 trace(Callstack_depth+1, "run") << "set r8/m8-at-rm32" << end(); 236 uint8_t* dest = effective_byte_address(modrm); 237 *dest = !CF; -238 trace(Callstack_depth+1, "run") << "storing " << NUM(*dest) << end(); +238 trace(Callstack_depth+1, "run") << "storing " << NUM(*dest) << end(); 239 break; 240 } 241 case 0x9c: { // set r8/m8-at-rm32 if SF and !ZF -242 const uint8_t modrm = next(); -243 trace(Callstack_depth+1, "run") << "set r8/m8-at-rm32" << end(); +242 const uint8_t modrm = next(); +243 trace(Callstack_depth+1, "run") << "set r8/m8-at-rm32" << end(); 244 uint8_t* dest = effective_byte_address(modrm); -245 *dest = (SF != OF); -246 trace(Callstack_depth+1, "run") << "storing " << NUM(*dest) << end(); +245 *dest = (SF != OF); +246 trace(Callstack_depth+1, "run") << "storing " << NUM(*dest) << end(); 247 break; 248 } 249 case 0x92: { // set r8/m8-at-rm32 if CF -250 const uint8_t modrm = next(); -251 trace(Callstack_depth+1, "run") << "set r8/m8-at-rm32" << end(); +250 const uint8_t modrm = next(); +251 trace(Callstack_depth+1, "run") << "set r8/m8-at-rm32" << end(); 252 uint8_t* dest = effective_byte_address(modrm); -253 *dest = CF; -254 trace(Callstack_depth+1, "run") << "storing " << NUM(*dest) << end(); +253 *dest = CF; +254 trace(Callstack_depth+1, "run") << "storing " << NUM(*dest) << end(); 255 break; 256 } 257 case 0x9e: { // set r8/m8-at-rm32 if SF or ZF -258 const uint8_t modrm = next(); -259 trace(Callstack_depth+1, "run") << "set r8/m8-at-rm32" << end(); +258 const uint8_t modrm = next(); +259 trace(Callstack_depth+1, "run") << "set r8/m8-at-rm32" << end(); 260 uint8_t* dest = effective_byte_address(modrm); -261 *dest = (ZF || SF != OF); -262 trace(Callstack_depth+1, "run") << "storing " << NUM(*dest) << end(); +261 *dest = (ZF || SF != OF); +262 trace(Callstack_depth+1, "run") << "storing " << NUM(*dest) << end(); 263 break; 264 } 265 case 0x96: { // set r8/m8-at-rm32 if ZF or CF -266 const uint8_t modrm = next(); -267 trace(Callstack_depth+1, "run") << "set r8/m8-at-rm32" << end(); +266 const uint8_t modrm = next(); +267 trace(Callstack_depth+1, "run") << "set r8/m8-at-rm32" << end(); 268 uint8_t* dest = effective_byte_address(modrm); -269 *dest = (ZF || CF); -270 trace(Callstack_depth+1, "run") << "storing " << NUM(*dest) << end(); +269 *dest = (ZF || CF); +270 trace(Callstack_depth+1, "run") << "storing " << NUM(*dest) << end(); 271 break; 272 } -- cgit 1.4.1-2-gfad0