From 7328af20a1921d9258a60803ee5367da97a6082e Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Mon, 13 Aug 2018 21:25:22 -0700 Subject: 4521 --- html/subx/013direct_addressing.cc.html | 202 ++++++++++++++++----------------- 1 file changed, 101 insertions(+), 101 deletions(-) (limited to 'html/subx/013direct_addressing.cc.html') diff --git a/html/subx/013direct_addressing.cc.html b/html/subx/013direct_addressing.cc.html index b7c416dd..69e32bc5 100644 --- a/html/subx/013direct_addressing.cc.html +++ b/html/subx/013direct_addressing.cc.html @@ -66,7 +66,7 @@ if ('onhashchange' in window) { 1 //: operating directly on a register 2 3 :(before "End Initialize Op Names(name)") - 4 put(name, "01", "add r32 to rm32"); + 4 put(name, "01", "add r32 to rm32"); 5 6 :(scenario add_r32_to_r32) 7 % Reg[EAX].i = 0x10; @@ -75,17 +75,17 @@ if ('onhashchange' in window) { 10 # op ModR/M SIB displacement immediate 11 01 d8 # add EBX to EAX 12 # ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) - 13 +run: add EBX to r/m32 - 14 +run: r/m32 is EAX + 13 +run: add EBX to r/m32 + 14 +run: r/m32 is EAX 15 +run: storing 0x00000011 16 17 :(before "End Single-Byte Opcodes") 18 case 0x01: { // add r32 to r/m32 - 19 uint8_t modrm = next(); + 19 uint8_t modrm = next(); 20 uint8_t arg2 = (modrm>>3)&0x7; - 21 trace(90, "run") << "add " << rname(arg2) << " to r/m32" << end(); + 21 trace(90, "run") << "add " << rname(arg2) << " to r/m32" << end(); 22 int32_t* arg1 = effective_address(modrm); - 23 BINARY_ARITHMETIC_OP(+, *arg1, Reg[arg2].i); + 23 BINARY_ARITHMETIC_OP(+, *arg1, Reg[arg2].i); 24 break; 25 } 26 @@ -101,15 +101,15 @@ if ('onhashchange' in window) { 36 switch (mod) { 37 case 3: 38 // mod 3 is just register direct addressing - 39 trace(90, "run") << "r/m32 is " << rname(rm) << end(); + 39 trace(90, "run") << "r/m32 is " << rname(rm) << end(); 40 return &Reg[rm].i; 41 // End Mod Special-cases(addr) 42 default: - 43 cerr << "unrecognized mod bits: " << NUM(mod) << '\n'; + 43 cerr << "unrecognized mod bits: " << NUM(mod) << '\n'; 44 exit(1); 45 } 46 //: other mods are indirect, and they'll set addr appropriately - 47 return mem_addr_i32(addr); + 47 return mem_addr_i32(addr); 48 } 49 50 string rname(uint8_t r) { @@ -122,14 +122,14 @@ if ('onhashchange' in window) { 57 case 5: return "EBP"; 58 case 6: return "ESI"; 59 case 7: return "EDI"; - 60 default: raise << "invalid register " << r << '\n' << end(); return ""; + 60 default: raise << "invalid register " << r << '\n' << end(); return ""; 61 } 62 } 63 64 //:: subtract 65 66 :(before "End Initialize Op Names(name)") - 67 put(name, "29", "subtract r32 from rm32"); + 67 put(name, "29", "subtract r32 from rm32"); 68 69 :(scenario subtract_r32_from_r32) 70 % Reg[EAX].i = 10; @@ -138,24 +138,24 @@ if ('onhashchange' in window) { 73 # op ModR/M SIB displacement immediate 74 29 d8 # subtract EBX from EAX 75 # ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) - 76 +run: subtract EBX from r/m32 - 77 +run: r/m32 is EAX + 76 +run: subtract EBX from r/m32 + 77 +run: r/m32 is EAX 78 +run: storing 0x00000009 79 80 :(before "End Single-Byte Opcodes") 81 case 0x29: { // subtract r32 from r/m32 - 82 uint8_t modrm = next(); + 82 uint8_t modrm = next(); 83 uint8_t arg2 = (modrm>>3)&0x7; - 84 trace(90, "run") << "subtract " << rname(arg2) << " from r/m32" << end(); + 84 trace(90, "run") << "subtract " << rname(arg2) << " from r/m32" << end(); 85 int32_t* arg1 = effective_address(modrm); - 86 BINARY_ARITHMETIC_OP(-, *arg1, Reg[arg2].i); + 86 BINARY_ARITHMETIC_OP(-, *arg1, Reg[arg2].i); 87 break; 88 } 89 90 //:: multiply 91 92 :(before "End Initialize Op Names(name)") - 93 put(name_0f, "af", "multiply rm32 into r32"); + 93 put(name_0f, "af", "multiply rm32 into r32"); 94 95 :(scenario multiply_r32_into_r32) 96 % Reg[EAX].i = 4; @@ -164,24 +164,24 @@ if ('onhashchange' in window) { 99 # op ModR/M SIB displacement immediate 100 0f af d8 # subtract EBX into EAX 101 # ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) -102 +run: multiply r/m32 into EBX -103 +run: r/m32 is EAX +102 +run: multiply r/m32 into EBX +103 +run: r/m32 is EAX 104 +run: storing 0x00000008 105 106 :(before "End Two-Byte Opcodes Starting With 0f") 107 case 0xaf: { // multiply r32 into r/m32 -108 uint8_t modrm = next(); +108 uint8_t modrm = next(); 109 uint8_t arg2 = (modrm>>3)&0x7; -110 trace(90, "run") << "multiply r/m32 into " << rname(arg2) << end(); +110 trace(90, "run") << "multiply r/m32 into " << rname(arg2) << end(); 111 int32_t* arg1 = effective_address(modrm); -112 BINARY_ARITHMETIC_OP(*, Reg[arg2].i, *arg1); +112 BINARY_ARITHMETIC_OP(*, Reg[arg2].i, *arg1); 113 break; 114 } 115 116 //:: and 117 118 :(before "End Initialize Op Names(name)") -119 put(name, "21", "rm32 = bitwise AND of r32 with rm32"); +119 put(name, "21", "rm32 = bitwise AND of r32 with rm32"); 120 121 :(scenario and_r32_with_r32) 122 % Reg[EAX].i = 0x0a0b0c0d; @@ -190,24 +190,24 @@ if ('onhashchange' in window) { 125 # op ModR/M SIB displacement immediate 126 21 d8 # and EBX with destination EAX 127 # ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) -128 +run: and EBX with r/m32 -129 +run: r/m32 is EAX +128 +run: and EBX with r/m32 +129 +run: r/m32 is EAX 130 +run: storing 0x0000000d 131 132 :(before "End Single-Byte Opcodes") 133 case 0x21: { // and r32 with r/m32 -134 uint8_t modrm = next(); +134 uint8_t modrm = next(); 135 uint8_t arg2 = (modrm>>3)&0x7; -136 trace(90, "run") << "and " << rname(arg2) << " with r/m32" << end(); +136 trace(90, "run") << "and " << rname(arg2) << " with r/m32" << end(); 137 int32_t* arg1 = effective_address(modrm); -138 BINARY_BITWISE_OP(&, *arg1, Reg[arg2].u); +138 BINARY_BITWISE_OP(&, *arg1, Reg[arg2].u); 139 break; 140 } 141 142 //:: or 143 144 :(before "End Initialize Op Names(name)") -145 put(name, "09", "rm32 = bitwise OR of r32 with rm32"); +145 put(name, "09", "rm32 = bitwise OR of r32 with rm32"); 146 147 :(scenario or_r32_with_r32) 148 % Reg[EAX].i = 0x0a0b0c0d; @@ -216,24 +216,24 @@ if ('onhashchange' in window) { 151 # op ModR/M SIB displacement immediate 152 09 d8 # or EBX with destination EAX 153 # ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) -154 +run: or EBX with r/m32 -155 +run: r/m32 is EAX +154 +run: or EBX with r/m32 +155 +run: r/m32 is EAX 156 +run: storing 0xaabbccdd 157 158 :(before "End Single-Byte Opcodes") 159 case 0x09: { // or r32 with r/m32 -160 uint8_t modrm = next(); +160 uint8_t modrm = next(); 161 uint8_t arg2 = (modrm>>3)&0x7; -162 trace(90, "run") << "or " << rname(arg2) << " with r/m32" << end(); +162 trace(90, "run") << "or " << rname(arg2) << " with r/m32" << end(); 163 int32_t* arg1 = effective_address(modrm); -164 BINARY_BITWISE_OP(|, *arg1, Reg[arg2].u); +164 BINARY_BITWISE_OP(|, *arg1, Reg[arg2].u); 165 break; 166 } 167 168 //:: xor 169 170 :(before "End Initialize Op Names(name)") -171 put(name, "31", "rm32 = bitwise XOR of r32 with rm32"); +171 put(name, "31", "rm32 = bitwise XOR of r32 with rm32"); 172 173 :(scenario xor_r32_with_r32) 174 % Reg[EAX].i = 0x0a0b0c0d; @@ -242,24 +242,24 @@ if ('onhashchange' in window) { 177 # op ModR/M SIB displacement immediate 178 31 d8 # xor EBX with destination EAX 179 # ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) -180 +run: xor EBX with r/m32 -181 +run: r/m32 is EAX +180 +run: xor EBX with r/m32 +181 +run: r/m32 is EAX 182 +run: storing 0xa0b0ccdd 183 184 :(before "End Single-Byte Opcodes") 185 case 0x31: { // xor r32 with r/m32 -186 uint8_t modrm = next(); +186 uint8_t modrm = next(); 187 uint8_t arg2 = (modrm>>3)&0x7; -188 trace(90, "run") << "xor " << rname(arg2) << " with r/m32" << end(); +188 trace(90, "run") << "xor " << rname(arg2) << " with r/m32" << end(); 189 int32_t* arg1 = effective_address(modrm); -190 BINARY_BITWISE_OP(^, *arg1, Reg[arg2].u); +190 BINARY_BITWISE_OP(^, *arg1, Reg[arg2].u); 191 break; 192 } 193 194 //:: not 195 196 :(before "End Initialize Op Names(name)") -197 put(name, "f7", "bitwise complement of rm32"); +197 put(name, "f7", "bitwise complement of rm32"); 198 199 :(scenario not_r32) 200 % Reg[EBX].i = 0x0f0f00ff; @@ -268,26 +268,26 @@ if ('onhashchange' in window) { 203 f7 c3 # not EBX 204 # ModR/M in binary: 11 (direct mode) 000 (unused) 011 (dest EBX) 205 +run: 'not' of r/m32 -206 +run: r/m32 is EBX +206 +run: r/m32 is EBX 207 +run: storing 0xf0f0ff00 208 209 :(before "End Single-Byte Opcodes") 210 case 0xf7: { // xor r32 with r/m32 -211 uint8_t modrm = next(); -212 trace(90, "run") << "'not' of r/m32" << end(); +211 uint8_t modrm = next(); +212 trace(90, "run") << "'not' of r/m32" << end(); 213 int32_t* arg1 = effective_address(modrm); 214 *arg1 = ~(*arg1); -215 trace(90, "run") << "storing 0x" << HEXWORD << *arg1 << end(); +215 trace(90, "run") << "storing 0x" << HEXWORD << *arg1 << end(); 216 SF = (*arg1 >> 31); 217 ZF = (*arg1 == 0); -218 OF = false; +218 OF = false; 219 break; 220 } 221 222 //:: compare (cmp) 223 224 :(before "End Initialize Op Names(name)") -225 put(name, "39", "set SF if rm32 < r32"); +225 put(name, "39", "set SF if rm32 < r32"); 226 227 :(scenario compare_r32_with_r32_greater) 228 % Reg[EAX].i = 0x0a0b0c0d; @@ -296,23 +296,23 @@ if ('onhashchange' in window) { 231 # op ModR/M SIB displacement immediate 232 39 d8 # compare EBX with EAX 233 # ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) -234 +run: compare EBX with r/m32 -235 +run: r/m32 is EAX +234 +run: compare EBX with r/m32 +235 +run: r/m32 is EAX 236 +run: SF=0; ZF=0; OF=0 237 238 :(before "End Single-Byte Opcodes") 239 case 0x39: { // set SF if r/m32 < r32 -240 uint8_t modrm = next(); +240 uint8_t modrm = next(); 241 uint8_t reg2 = (modrm>>3)&0x7; -242 trace(90, "run") << "compare " << rname(reg2) << " with r/m32" << end(); +242 trace(90, "run") << "compare " << rname(reg2) << " with r/m32" << end(); 243 int32_t* arg1 = effective_address(modrm); 244 int32_t arg2 = Reg[reg2].i; 245 int32_t tmp1 = *arg1 - arg2; 246 SF = (tmp1 < 0); 247 ZF = (tmp1 == 0); 248 int64_t tmp2 = *arg1 - arg2; -249 OF = (tmp1 != tmp2); -250 trace(90, "run") << "SF=" << SF << "; ZF=" << ZF << "; OF=" << OF << end(); +249 OF = (tmp1 != tmp2); +250 trace(90, "run") << "SF=" << SF << "; ZF=" << ZF << "; OF=" << OF << end(); 251 break; 252 } 253 @@ -323,8 +323,8 @@ if ('onhashchange' in window) { 258 # op ModR/M SIB displacement immediate 259 39 d8 # compare EBX with EAX 260 # ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) -261 +run: compare EBX with r/m32 -262 +run: r/m32 is EAX +261 +run: compare EBX with r/m32 +262 +run: r/m32 is EAX 263 +run: SF=1; ZF=0; OF=0 264 265 :(scenario compare_r32_with_r32_equal) @@ -334,14 +334,14 @@ if ('onhashchange' in window) { 269 # op ModR/M SIB displacement immediate 270 39 d8 # compare EBX with EAX 271 # ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) -272 +run: compare EBX with r/m32 -273 +run: r/m32 is EAX +272 +run: compare EBX with r/m32 +273 +run: r/m32 is EAX 274 +run: SF=0; ZF=1; OF=0 275 276 //:: copy (mov) 277 278 :(before "End Initialize Op Names(name)") -279 put(name, "89", "copy r32 to rm32"); +279 put(name, "89", "copy r32 to rm32"); 280 281 :(scenario copy_r32_to_r32) 282 % Reg[EBX].i = 0xaf; @@ -349,25 +349,25 @@ if ('onhashchange' in window) { 284 # op ModR/M SIB displacement immediate 285 89 d8 # copy EBX to EAX 286 # ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) -287 +run: copy EBX to r/m32 -288 +run: r/m32 is EAX +287 +run: copy EBX to r/m32 +288 +run: r/m32 is EAX 289 +run: storing 0x000000af 290 291 :(before "End Single-Byte Opcodes") 292 case 0x89: { // copy r32 to r/m32 -293 uint8_t modrm = next(); +293 uint8_t modrm = next(); 294 uint8_t reg2 = (modrm>>3)&0x7; -295 trace(90, "run") << "copy " << rname(reg2) << " to r/m32" << end(); +295 trace(90, "run") << "copy " << rname(reg2) << " to r/m32" << end(); 296 int32_t* arg1 = effective_address(modrm); 297 *arg1 = Reg[reg2].i; -298 trace(90, "run") << "storing 0x" << HEXWORD << *arg1 << end(); +298 trace(90, "run") << "storing 0x" << HEXWORD << *arg1 << end(); 299 break; 300 } 301 302 //:: xchg 303 304 :(before "End Initialize Op Names(name)") -305 put(name, "87", "swap the contents of r32 and rm32"); +305 put(name, "87", "swap the contents of r32 and rm32"); 306 307 :(scenario xchg_r32_with_r32) 308 % Reg[EBX].i = 0xaf; @@ -376,36 +376,36 @@ if ('onhashchange' in window) { 311 # op ModR/M SIB displacement immediate 312 87 d8 # exchange EBX with EAX 313 # ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) -314 +run: exchange EBX with r/m32 -315 +run: r/m32 is EAX +314 +run: exchange EBX with r/m32 +315 +run: r/m32 is EAX 316 +run: storing 0x000000af in r/m32 -317 +run: storing 0x0000002e in EBX +317 +run: storing 0x0000002e in EBX 318 319 :(before "End Single-Byte Opcodes") 320 case 0x87: { // exchange r32 with r/m32 -321 uint8_t modrm = next(); +321 uint8_t modrm = next(); 322 uint8_t reg2 = (modrm>>3)&0x7; -323 trace(90, "run") << "exchange " << rname(reg2) << " with r/m32" << end(); +323 trace(90, "run") << "exchange " << rname(reg2) << " with r/m32" << end(); 324 int32_t* arg1 = effective_address(modrm); 325 int32_t tmp = *arg1; 326 *arg1 = Reg[reg2].i; 327 Reg[reg2].i = tmp; -328 trace(90, "run") << "storing 0x" << HEXWORD << *arg1 << " in r/m32" << end(); -329 trace(90, "run") << "storing 0x" << HEXWORD << Reg[reg2].i << " in " << rname(reg2) << end(); +328 trace(90, "run") << "storing 0x" << HEXWORD << *arg1 << " in r/m32" << end(); +329 trace(90, "run") << "storing 0x" << HEXWORD << Reg[reg2].i << " in " << rname(reg2) << end(); 330 break; 331 } 332 333 //:: push 334 335 :(before "End Initialize Op Names(name)") -336 put(name, "50", "push R0 (EAX) to stack"); -337 put(name, "51", "push R1 (ECX) to stack"); -338 put(name, "52", "push R2 (EDX) to stack"); -339 put(name, "53", "push R3 (EBX) to stack"); -340 put(name, "54", "push R4 (ESP) to stack"); -341 put(name, "55", "push R5 (EBP) to stack"); -342 put(name, "56", "push R6 (ESI) to stack"); -343 put(name, "57", "push R7 (EDI) to stack"); +336 put(name, "50", "push R0 (EAX) to stack"); +337 put(name, "51", "push R1 (ECX) to stack"); +338 put(name, "52", "push R2 (EDX) to stack"); +339 put(name, "53", "push R3 (EBX) to stack"); +340 put(name, "54", "push R4 (ESP) to stack"); +341 put(name, "55", "push R5 (EBP) to stack"); +342 put(name, "56", "push R6 (ESI) to stack"); +343 put(name, "57", "push R7 (EDI) to stack"); 344 345 :(scenario push_r32) 346 % Reg[ESP].u = 0x64; @@ -413,8 +413,8 @@ if ('onhashchange' in window) { 348 == 0x1 349 # op ModR/M SIB displacement immediate 350 53 # push EBX to stack -351 +run: push EBX -352 +run: decrementing ESP to 0x00000060 +351 +run: push EBX +352 +run: decrementing ESP to 0x00000060 353 +run: pushing value 0x0000000a 354 355 :(before "End Single-Byte Opcodes") @@ -426,8 +426,8 @@ if ('onhashchange' in window) { 361 case 0x55: 362 case 0x56: 363 case 0x57: { // push r32 to stack -364 uint8_t reg = op & 0x7; -365 trace(90, "run") << "push " << rname(reg) << end(); +364 uint8_t reg = op & 0x7; +365 trace(90, "run") << "push " << rname(reg) << end(); 366 //? cerr << "push: " << NUM(reg) << ": " << Reg[reg].u << " => " << Reg[ESP].u << '\n'; 367 push(Reg[reg].u); 368 break; @@ -435,22 +435,22 @@ if ('onhashchange' in window) { 370 :(code) 371 void push(uint32_t val) { 372 Reg[ESP].u -= 4; -373 trace(90, "run") << "decrementing ESP to 0x" << HEXWORD << Reg[ESP].u << end(); -374 trace(90, "run") << "pushing value 0x" << HEXWORD << val << end(); -375 write_mem_u32(Reg[ESP].u, val); +373 trace(90, "run") << "decrementing ESP to 0x" << HEXWORD << Reg[ESP].u << end(); +374 trace(90, "run") << "pushing value 0x" << HEXWORD << val << end(); +375 write_mem_u32(Reg[ESP].u, val); 376 } 377 378 //:: pop 379 380 :(before "End Initialize Op Names(name)") -381 put(name, "58", "pop top of stack to R0 (EAX)"); -382 put(name, "59", "pop top of stack to R1 (ECX)"); -383 put(name, "5a", "pop top of stack to R2 (EDX)"); -384 put(name, "5b", "pop top of stack to R3 (EBX)"); -385 put(name, "5c", "pop top of stack to R4 (ESP)"); -386 put(name, "5d", "pop top of stack to R5 (EBP)"); -387 put(name, "5e", "pop top of stack to R6 (ESI)"); -388 put(name, "5f", "pop top of stack to R7 (EDI)"); +381 put(name, "58", "pop top of stack to R0 (EAX)"); +382 put(name, "59", "pop top of stack to R1 (ECX)"); +383 put(name, "5a", "pop top of stack to R2 (EDX)"); +384 put(name, "5b", "pop top of stack to R3 (EBX)"); +385 put(name, "5c", "pop top of stack to R4 (ESP)"); +386 put(name, "5d", "pop top of stack to R5 (EBP)"); +387 put(name, "5e", "pop top of stack to R6 (ESI)"); +388 put(name, "5f", "pop top of stack to R7 (EDI)"); 389 390 :(scenario pop_r32) 391 % Reg[ESP].u = 0x60; @@ -460,9 +460,9 @@ if ('onhashchange' in window) { 395 5b # pop stack to EBX 396 == 0x60 # data segment 397 0a 00 00 00 # 0x0a -398 +run: pop into EBX +398 +run: pop into EBX 399 +run: popping value 0x0000000a -400 +run: incrementing ESP to 0x00000064 +400 +run: incrementing ESP to 0x00000064 401 402 :(before "End Single-Byte Opcodes") 403 case 0x58: @@ -473,8 +473,8 @@ if ('onhashchange' in window) { 408 case 0x5d: 409 case 0x5e: 410 case 0x5f: { // pop stack into r32 -411 uint8_t reg = op & 0x7; -412 trace(90, "run") << "pop into " << rname(reg) << end(); +411 uint8_t reg = op & 0x7; +412 trace(90, "run") << "pop into " << rname(reg) << end(); 413 //? cerr << "pop from " << Reg[ESP].u << '\n'; 414 Reg[reg].u = pop(); 415 //? cerr << "=> " << NUM(reg) << ": " << Reg[reg].u << '\n'; @@ -482,10 +482,10 @@ if ('onhashchange' in window) { 417 } 418 :(code) 419 uint32_t pop() { -420 uint32_t result = read_mem_u32(Reg[ESP].u); -421 trace(90, "run") << "popping value 0x" << HEXWORD << result << end(); +420 uint32_t result = read_mem_u32(Reg[ESP].u); +421 trace(90, "run") << "popping value 0x" << HEXWORD << result << end(); 422 Reg[ESP].u += 4; -423 trace(90, "run") << "incrementing ESP to 0x" << HEXWORD << Reg[ESP].u << end(); +423 trace(90, "run") << "incrementing ESP to 0x" << HEXWORD << Reg[ESP].u << end(); 424 return result; 425 } -- cgit 1.4.1-2-gfad0