From 5fe060d582d4a82444243a28b18085c971a85628 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Fri, 27 Jul 2018 17:07:52 -0700 Subject: 4447 --- html/subx/014immediate_addressing.cc.html | 544 ++++++++++++++++++++++++++++++ 1 file changed, 544 insertions(+) create mode 100644 html/subx/014immediate_addressing.cc.html (limited to 'html/subx/014immediate_addressing.cc.html') diff --git a/html/subx/014immediate_addressing.cc.html b/html/subx/014immediate_addressing.cc.html new file mode 100644 index 00000000..e4119c28 --- /dev/null +++ b/html/subx/014immediate_addressing.cc.html @@ -0,0 +1,544 @@ + + + + +Mu - subx/014immediate_addressing.cc + + + + + + + + + + +
+  1 //: instructions that (immediately) contain an argument to act with
+  2 
+  3 :(before "End Initialize Op Names(name)")
+  4 put(name, "81", "combine rm32 with imm32 based on subop");
+  5 
+  6 :(scenario add_imm32_to_r32)
+  7 % Reg[EBX].i = 1;
+  8 == 0x1
+  9 # op  ModR/M  SIB   displacement  immediate
+ 10   81  c3                          0a 0b 0c 0d  # add 0x0d0c0b0a to EBX
+ 11 # ModR/M in binary: 11 (direct mode) 000 (add imm32) 011 (dest EBX)
+ 12 +run: combine imm32 0x0d0c0b0a with r/m32
+ 13 +run: r/m32 is EBX
+ 14 +run: subop add
+ 15 +run: storing 0x0d0c0b0b
+ 16 
+ 17 :(before "End Single-Byte Opcodes")
+ 18 case 0x81: {  // combine imm32 with r/m32
+ 19   uint8_t modrm = next();
+ 20   int32_t arg2 = imm32();
+ 21   trace(90, "run") << "combine imm32 0x" << HEXWORD << arg2 << " with r/m32" << end();
+ 22   int32_t* arg1 = effective_address(modrm);
+ 23   uint8_t subop = (modrm>>3)&0x7;  // middle 3 'reg opcode' bits
+ 24   switch (subop) {
+ 25   case 0:
+ 26     trace(90, "run") << "subop add" << end();
+ 27     BINARY_ARITHMETIC_OP(+, *arg1, arg2);
+ 28     break;
+ 29   // End Op 81 Subops
+ 30   default:
+ 31     cerr << "unrecognized sub-opcode after 81: " << NUM(subop) << '\n';
+ 32     exit(1);
+ 33   }
+ 34   break;
+ 35 }
+ 36 
+ 37 //:
+ 38 
+ 39 :(scenario add_imm32_to_mem_at_r32)
+ 40 % Reg[EBX].i = 0x60;
+ 41 == 0x01  # code segment
+ 42 # op  ModR/M  SIB   displacement  immediate
+ 43   81  03                          0a 0b 0c 0d  # add 0x0d0c0b0a to *EBX
+ 44 # ModR/M in binary: 00 (indirect mode) 000 (add imm32) 011 (dest EBX)
+ 45 == 0x60  # data segment
+ 46 01 00 00 00  # 1
+ 47 +run: combine imm32 0x0d0c0b0a with r/m32
+ 48 +run: effective address is 0x60 (EBX)
+ 49 +run: subop add
+ 50 +run: storing 0x0d0c0b0b
+ 51 
+ 52 //:: subtract
+ 53 
+ 54 :(before "End Initialize Op Names(name)")
+ 55 put(name, "2d", "subtract imm32 from R0 (EAX)");
+ 56 
+ 57 :(scenario subtract_imm32_from_eax)
+ 58 % Reg[EAX].i = 0x0d0c0baa;
+ 59 == 0x1
+ 60 # op  ModR/M  SIB   displacement  immediate
+ 61   2d                              0a 0b 0c 0d  # subtract 0x0d0c0b0a from EAX
+ 62 +run: subtract imm32 0x0d0c0b0a from EAX
+ 63 +run: storing 0x000000a0
+ 64 
+ 65 :(before "End Single-Byte Opcodes")
+ 66 case 0x2d: {  // subtract imm32 from EAX
+ 67   int32_t arg2 = imm32();
+ 68   trace(90, "run") << "subtract imm32 0x" << HEXWORD << arg2 << " from EAX" << end();
+ 69   BINARY_ARITHMETIC_OP(-, Reg[EAX].i, arg2);
+ 70   break;
+ 71 }
+ 72 
+ 73 //:
+ 74 
+ 75 :(scenario subtract_imm32_from_mem_at_r32)
+ 76 % Reg[EBX].i = 0x60;
+ 77 == 0x01  # code segment
+ 78 # op  ModR/M  SIB   displacement  immediate
+ 79   81  2b                          01 00 00 00  # subtract 1 from *EBX
+ 80 # ModR/M in binary: 00 (indirect mode) 101 (subtract imm32) 011 (dest EBX)
+ 81 == 0x60  # data segment
+ 82 0a 00 00 00  # 10
+ 83 +run: combine imm32 0x00000001 with r/m32
+ 84 +run: effective address is 0x60 (EBX)
+ 85 +run: subop subtract
+ 86 +run: storing 0x00000009
+ 87 
+ 88 :(before "End Op 81 Subops")
+ 89 case 5: {
+ 90   trace(90, "run") << "subop subtract" << end();
+ 91   BINARY_ARITHMETIC_OP(-, *arg1, arg2);
+ 92   break;
+ 93 }
+ 94 
+ 95 //:
+ 96 
+ 97 :(scenario subtract_imm32_from_r32)
+ 98 % Reg[EBX].i = 10;
+ 99 == 0x1
+100 # op  ModR/M  SIB   displacement  immediate
+101   81  eb                          01 00 00 00  # subtract 1 from EBX
+102 # ModR/M in binary: 11 (direct mode) 101 (subtract imm32) 011 (dest EBX)
+103 +run: combine imm32 0x00000001 with r/m32
+104 +run: r/m32 is EBX
+105 +run: subop subtract
+106 +run: storing 0x00000009
+107 
+108 //:: and
+109 
+110 :(before "End Initialize Op Names(name)")
+111 put(name, "25", "R0 = bitwise AND of imm32 with R0 (EAX)");
+112 
+113 :(scenario and_imm32_with_eax)
+114 % Reg[EAX].i = 0xff;
+115 == 0x1
+116 # op  ModR/M  SIB   displacement  immediate
+117   25                              0a 0b 0c 0d  # and 0x0d0c0b0a with EAX
+118 +run: and imm32 0x0d0c0b0a with EAX
+119 +run: storing 0x0000000a
+120 
+121 :(before "End Single-Byte Opcodes")
+122 case 0x25: {  // and imm32 with EAX
+123   int32_t arg2 = imm32();
+124   trace(90, "run") << "and imm32 0x" << HEXWORD << arg2 << " with EAX" << end();
+125   BINARY_BITWISE_OP(&, Reg[EAX].i, arg2);
+126   break;
+127 }
+128 
+129 //:
+130 
+131 :(scenario and_imm32_with_mem_at_r32)
+132 % Reg[EBX].i = 0x60;
+133 == 0x01  # code segment
+134 # op  ModR/M  SIB   displacement  immediate
+135   81  23                          0a 0b 0c 0d  # and 0x0d0c0b0a with *EBX
+136 # ModR/M in binary: 00 (indirect mode) 100 (and imm32) 011 (dest EBX)
+137 == 0x60  # data segment
+138 ff 00 00 00  # 0xff
+139 +run: combine imm32 0x0d0c0b0a with r/m32
+140 +run: effective address is 0x60 (EBX)
+141 +run: subop and
+142 +run: storing 0x0000000a
+143 
+144 :(before "End Op 81 Subops")
+145 case 4: {
+146   trace(90, "run") << "subop and" << end();
+147   BINARY_BITWISE_OP(&, *arg1, arg2);
+148   break;
+149 }
+150 
+151 //:
+152 
+153 :(scenario and_imm32_with_r32)
+154 % Reg[EBX].i = 0xff;
+155 == 0x1
+156 # op  ModR/M  SIB   displacement  immediate
+157   81  e3                          0a 0b 0c 0d  # and 0x0d0c0b0a with EBX
+158 # ModR/M in binary: 11 (direct mode) 100 (and imm32) 011 (dest EBX)
+159 +run: combine imm32 0x0d0c0b0a with r/m32
+160 +run: r/m32 is EBX
+161 +run: subop and
+162 +run: storing 0x0000000a
+163 
+164 //:: or
+165 
+166 :(before "End Initialize Op Names(name)")
+167 put(name, "0d", "R0 = bitwise OR of imm32 with R0 (EAX)");
+168 
+169 :(scenario or_imm32_with_eax)
+170 % Reg[EAX].i = 0xd0c0b0a0;
+171 == 0x1
+172 # op  ModR/M  SIB   displacement  immediate
+173   0d                              0a 0b 0c 0d  # or 0x0d0c0b0a with EAX
+174 +run: or imm32 0x0d0c0b0a with EAX
+175 +run: storing 0xddccbbaa
+176 
+177 :(before "End Single-Byte Opcodes")
+178 case 0x0d: {  // or imm32 with EAX
+179   int32_t arg2 = imm32();
+180   trace(90, "run") << "or imm32 0x" << HEXWORD << arg2 << " with EAX" << end();
+181   BINARY_BITWISE_OP(|, Reg[EAX].i, arg2);
+182   break;
+183 }
+184 
+185 //:
+186 
+187 :(scenario or_imm32_with_mem_at_r32)
+188 % Reg[EBX].i = 0x60;
+189 == 0x01  # code segment
+190 # op  ModR/M  SIB   displacement  immediate
+191   81  0b                          0a 0b 0c 0d  # or 0x0d0c0b0a with *EBX
+192 # ModR/M in binary: 00 (indirect mode) 001 (or imm32) 011 (dest EBX)
+193 == 0x60  # data segment
+194 a0 b0 c0 d0  # 0xd0c0b0a0
+195 +run: combine imm32 0x0d0c0b0a with r/m32
+196 +run: effective address is 0x60 (EBX)
+197 +run: subop or
+198 +run: storing 0xddccbbaa
+199 
+200 :(before "End Op 81 Subops")
+201 case 1: {
+202   trace(90, "run") << "subop or" << end();
+203   BINARY_BITWISE_OP(|, *arg1, arg2);
+204   break;
+205 }
+206 
+207 :(scenario or_imm32_with_r32)
+208 % Reg[EBX].i = 0xd0c0b0a0;
+209 == 0x1
+210 # op  ModR/M  SIB   displacement  immediate
+211   81  cb                          0a 0b 0c 0d  # or 0x0d0c0b0a with EBX
+212 # ModR/M in binary: 11 (direct mode) 001 (or imm32) 011 (dest EBX)
+213 +run: combine imm32 0x0d0c0b0a with r/m32
+214 +run: r/m32 is EBX
+215 +run: subop or
+216 +run: storing 0xddccbbaa
+217 
+218 //:: xor
+219 
+220 :(before "End Initialize Op Names(name)")
+221 put(name, "35", "R0 = bitwise XOR of imm32 with R0 (EAX)");
+222 
+223 :(scenario xor_imm32_with_eax)
+224 % Reg[EAX].i = 0xddccb0a0;
+225 == 0x1
+226 # op  ModR/M  SIB   displacement  immediate
+227   35                              0a 0b 0c 0d  # xor 0x0d0c0b0a with EAX
+228 +run: xor imm32 0x0d0c0b0a with EAX
+229 +run: storing 0xd0c0bbaa
+230 
+231 :(before "End Single-Byte Opcodes")
+232 case 0x35: {  // xor imm32 with EAX
+233   int32_t arg2 = imm32();
+234   trace(90, "run") << "xor imm32 0x" << HEXWORD << arg2 << " with EAX" << end();
+235   BINARY_BITWISE_OP(^, Reg[EAX].i, arg2);
+236   break;
+237 }
+238 
+239 //:
+240 
+241 :(scenario xor_imm32_with_mem_at_r32)
+242 % Reg[EBX].i = 0x60;
+243 == 0x01  # code segment
+244 # op  ModR/M  SIB   displacement  immediate
+245   81  33                          0a 0b 0c 0d  # xor 0x0d0c0b0a with *EBX
+246 # ModR/M in binary: 00 (indirect mode) 110 (xor imm32) 011 (dest EBX)
+247 == 0x60  # data segment
+248 a0 b0 c0 d0  # 0xd0c0b0a0
+249 +run: combine imm32 0x0d0c0b0a with r/m32
+250 +run: effective address is 0x60 (EBX)
+251 +run: subop xor
+252 +run: storing 0xddccbbaa
+253 
+254 :(before "End Op 81 Subops")
+255 case 6: {
+256   trace(90, "run") << "subop xor" << end();
+257   BINARY_BITWISE_OP(^, *arg1, arg2);
+258   break;
+259 }
+260 
+261 :(scenario xor_imm32_with_r32)
+262 % Reg[EBX].i = 0xd0c0b0a0;
+263 == 0x1
+264 # op  ModR/M  SIB   displacement  immediate
+265   81  f3                          0a 0b 0c 0d  # xor 0x0d0c0b0a with EBX
+266 # ModR/M in binary: 11 (direct mode) 110 (xor imm32) 011 (dest EBX)
+267 +run: combine imm32 0x0d0c0b0a with r/m32
+268 +run: r/m32 is EBX
+269 +run: subop xor
+270 +run: storing 0xddccbbaa
+271 
+272 //:: compare (cmp)
+273 
+274 :(before "End Initialize Op Names(name)")
+275 put(name, "3d", "subtract imm32 from R0 (EAX)");
+276 
+277 :(scenario compare_imm32_with_eax_greater)
+278 % Reg[EAX].i = 0x0d0c0b0a;
+279 == 0x1
+280 # op  ModR/M  SIB   displacement  immediate
+281   3d                              07 0b 0c 0d  # compare 0x0d0c0b07 with EAX
+282 +run: compare EAX and imm32 0x0d0c0b07
+283 +run: SF=0; ZF=0; OF=0
+284 
+285 :(before "End Single-Byte Opcodes")
+286 case 0x3d: {  // subtract imm32 from EAX
+287   int32_t arg1 = Reg[EAX].i;
+288   int32_t arg2 = imm32();
+289   trace(90, "run") << "compare EAX and imm32 0x" << HEXWORD << arg2 << end();
+290   int32_t tmp1 = arg1 - arg2;
+291   SF = (tmp1 < 0);
+292   ZF = (tmp1 == 0);
+293   int64_t tmp2 = arg1 - arg2;
+294   OF = (tmp1 != tmp2);
+295   trace(90, "run") << "SF=" << SF << "; ZF=" << ZF << "; OF=" << OF << end();
+296   break;
+297 }
+298 
+299 :(scenario compare_imm32_with_eax_lesser)
+300 % Reg[EAX].i = 0x0d0c0b07;
+301 == 0x1
+302 # op  ModR/M  SIB   displacement  immediate
+303   3d                              0a 0b 0c 0d  # compare 0x0d0c0b0a with EAX
+304 +run: compare EAX and imm32 0x0d0c0b0a
+305 +run: SF=1; ZF=0; OF=0
+306 
+307 :(scenario compare_imm32_with_eax_equal)
+308 % Reg[EAX].i = 0x0d0c0b0a;
+309 == 0x1
+310 # op  ModR/M  SIB   displacement  immediate
+311   3d                              0a 0b 0c 0d  # compare 0x0d0c0b0a with EAX
+312 +run: compare EAX and imm32 0x0d0c0b0a
+313 +run: SF=0; ZF=1; OF=0
+314 
+315 //:
+316 
+317 :(scenario compare_imm32_with_r32_greater)
+318 % Reg[EBX].i = 0x0d0c0b0a;
+319 == 0x1
+320 # op  ModR/M  SIB   displacement  immediate
+321   81  fb                          07 0b 0c 0d  # compare 0x0d0c0b07 with EBX
+322 # ModR/M in binary: 11 (direct mode) 111 (compare imm32) 011 (dest EBX)
+323 +run: combine imm32 0x0d0c0b07 with r/m32
+324 +run: r/m32 is EBX
+325 +run: SF=0; ZF=0; OF=0
+326 
+327 :(before "End Op 81 Subops")
+328 case 7: {
+329   trace(90, "run") << "subop compare" << end();
+330   int32_t tmp1 = *arg1 - arg2;
+331   SF = (tmp1 < 0);
+332   ZF = (tmp1 == 0);
+333   int64_t tmp2 = *arg1 - arg2;
+334   OF = (tmp1 != tmp2);
+335   trace(90, "run") << "SF=" << SF << "; ZF=" << ZF << "; OF=" << OF << end();
+336   break;
+337 }
+338 
+339 :(scenario compare_imm32_with_r32_lesser)
+340 % Reg[EBX].i = 0x0d0c0b07;
+341 == 0x1
+342 # op  ModR/M  SIB   displacement  immediate
+343   81  fb                          0a 0b 0c 0d  # compare 0x0d0c0b0a with EBX
+344 # ModR/M in binary: 11 (direct mode) 111 (compare imm32) 011 (dest EBX)
+345 +run: combine imm32 0x0d0c0b0a with r/m32
+346 +run: r/m32 is EBX
+347 +run: SF=1; ZF=0; OF=0
+348 
+349 :(scenario compare_imm32_with_r32_equal)
+350 % Reg[EBX].i = 0x0d0c0b0a;
+351 == 0x1
+352 # op  ModR/M  SIB   displacement  immediate
+353   81  fb                          0a 0b 0c 0d  # compare 0x0d0c0b0a with EBX
+354 # ModR/M in binary: 11 (direct mode) 111 (compare imm32) 011 (dest EBX)
+355 +run: combine imm32 0x0d0c0b0a with r/m32
+356 +run: r/m32 is EBX
+357 +run: SF=0; ZF=1; OF=0
+358 
+359 :(scenario compare_imm32_with_mem_at_r32_greater)
+360 % Reg[EBX].i = 0x60;
+361 == 0x01  # code segment
+362 # op  ModR/M  SIB   displacement  immediate
+363   81  3b                          07 0b 0c 0d  # compare 0x0d0c0b07 with *EBX
+364 # ModR/M in binary: 00 (indirect mode) 111 (compare imm32) 011 (dest EBX)
+365 == 0x60  # data segment
+366 0a 0b 0c 0d  # 0x0d0c0b0a
+367 +run: combine imm32 0x0d0c0b07 with r/m32
+368 +run: effective address is 0x60 (EBX)
+369 +run: SF=0; ZF=0; OF=0
+370 
+371 :(scenario compare_imm32_with_mem_at_r32_lesser)
+372 % Reg[EBX].i = 0x60;
+373 == 0x01  # code segment
+374 # op  ModR/M  SIB   displacement  immediate
+375   81  3b                          0a 0b 0c 0d  # compare 0x0d0c0b0a with *EBX
+376 # ModR/M in binary: 00 (indirect mode) 111 (compare imm32) 011 (dest EBX)
+377 == 0x60  # data segment
+378 07 0b 0c 0d  # 0x0d0c0b07
+379 +run: combine imm32 0x0d0c0b0a with r/m32
+380 +run: effective address is 0x60 (EBX)
+381 +run: SF=1; ZF=0; OF=0
+382 
+383 :(scenario compare_imm32_with_mem_at_r32_equal)
+384 % Reg[EBX].i = 0x0d0c0b0a;
+385 % Reg[EBX].i = 0x60;
+386 == 0x01  # code segment
+387 # op  ModR/M  SIB   displacement  immediate
+388   81  3b                          0a 0b 0c 0d  # compare 0x0d0c0b0a with *EBX
+389 # ModR/M in binary: 00 (indirect mode) 111 (compare imm32) 011 (dest EBX)
+390 == 0x60  # data segment
+391 0a 0b 0c 0d  # 0x0d0c0b0a
+392 +run: combine imm32 0x0d0c0b0a with r/m32
+393 +run: effective address is 0x60 (EBX)
+394 +run: SF=0; ZF=1; OF=0
+395 
+396 //:: copy (mov)
+397 
+398 :(before "End Initialize Op Names(name)")
+399 put(name, "b8", "copy imm32 to R0 (EAX)");
+400 put(name, "b9", "copy imm32 to R1 (ECX)");
+401 put(name, "ba", "copy imm32 to R2 (EDX)");
+402 put(name, "bb", "copy imm32 to R3 (EBX)");
+403 put(name, "bc", "copy imm32 to R4 (ESP)");
+404 put(name, "bd", "copy imm32 to R5 (EBP)");
+405 put(name, "be", "copy imm32 to R6 (ESI)");
+406 put(name, "bf", "copy imm32 to R7 (EDI)");
+407 
+408 :(scenario copy_imm32_to_r32)
+409 == 0x1
+410 # op  ModR/M  SIB   displacement  immediate
+411   bb                              0a 0b 0c 0d  # copy 0x0d0c0b0a to EBX
+412 +run: copy imm32 0x0d0c0b0a to EBX
+413 
+414 :(before "End Single-Byte Opcodes")
+415 case 0xb8:
+416 case 0xb9:
+417 case 0xba:
+418 case 0xbb:
+419 case 0xbc:
+420 case 0xbd:
+421 case 0xbe:
+422 case 0xbf: {  // copy imm32 to r32
+423   uint8_t reg1 = op & 0x7;
+424   int32_t arg2 = imm32();
+425   trace(90, "run") << "copy imm32 0x" << HEXWORD << arg2 << " to " << rname(reg1) << end();
+426   Reg[reg1].i = arg2;
+427   break;
+428 }
+429 
+430 //:
+431 
+432 :(before "End Initialize Op Names(name)")
+433 put(name, "c7", "copy imm32 to rm32");
+434 
+435 :(scenario copy_imm32_to_mem_at_r32)
+436 % Reg[EBX].i = 0x60;
+437 == 0x1
+438 # op  ModR/M  SIB   displacement  immediate
+439   c7  03                          0a 0b 0c 0d  # copy 0x0d0c0b0a to *EBX
+440 # ModR/M in binary: 00 (indirect mode) 000 (unused) 011 (dest EBX)
+441 +run: copy imm32 0x0d0c0b0a to r/m32
+442 +run: effective address is 0x60 (EBX)
+443 
+444 :(before "End Single-Byte Opcodes")
+445 case 0xc7: {  // copy imm32 to r32
+446   uint8_t modrm = next();
+447   int32_t arg2 = imm32();
+448   trace(90, "run") << "copy imm32 0x" << HEXWORD << arg2 << " to r/m32" << end();
+449   int32_t* arg1 = effective_address(modrm);
+450   *arg1 = arg2;
+451   break;
+452 }
+453 
+454 //:: push
+455 
+456 :(before "End Initialize Op Names(name)")
+457 put(name, "68", "push imm32 to stack");
+458 
+459 :(scenario push_imm32)
+460 % Reg[ESP].u = 0x14;
+461 == 0x1
+462 # op  ModR/M  SIB   displacement  immediate
+463   68                              af 00 00 00  # push *EAX to stack
+464 +run: push imm32 0x000000af
+465 +run: ESP is now 0x00000010
+466 +run: contents at ESP: 0x000000af
+467 
+468 :(before "End Single-Byte Opcodes")
+469 case 0x68: {
+470   int32_t val = imm32();
+471   trace(90, "run") << "push imm32 0x" << HEXWORD << val << end();
+472   Reg[ESP].u -= 4;
+473   write_mem_i32(Reg[ESP].u, val);
+474   trace(90, "run") << "ESP is now 0x" << HEXWORD << Reg[ESP].u << end();
+475   trace(90, "run") << "contents at ESP: 0x" << HEXWORD << read_mem_u32(Reg[ESP].u) << end();
+476   break;
+477 }
+
+ + + -- cgit 1.4.1-2-gfad0