From 6e1eeeebfb453fa7c871869c19375ce60fbd7413 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sat, 27 Jul 2019 16:01:55 -0700 Subject: 5485 - promote SubX to top-level --- html/subx/021byte_addressing.cc.html | 239 ----------------------------------- 1 file changed, 239 deletions(-) delete mode 100644 html/subx/021byte_addressing.cc.html (limited to 'html/subx/021byte_addressing.cc.html') diff --git a/html/subx/021byte_addressing.cc.html b/html/subx/021byte_addressing.cc.html deleted file mode 100644 index 32a3d7bb..00000000 --- a/html/subx/021byte_addressing.cc.html +++ /dev/null @@ -1,239 +0,0 @@ - - - - -Mu - subx/021byte_addressing.cc - - - - - - - - - - -https://github.com/akkartik/mu/blob/master/subx/021byte_addressing.cc -
-  1 //: SubX mostly deals with instructions operating on 32-bit operands, but we
-  2 //: still need to deal with raw bytes for strings and so on.
-  3 
-  4 //: Unfortunately the register encodings when dealing with bytes are a mess.
-  5 //: We need a special case for them.
-  6 :(code)
-  7 string rname_8bit(uint8_t r) {
-  8   switch (r) {
-  9   case 0: return "AL";  // lowest byte of EAX
- 10   case 1: return "CL";  // lowest byte of ECX
- 11   case 2: return "DL";  // lowest byte of EDX
- 12   case 3: return "BL";  // lowest byte of EBX
- 13   case 4: return "AH";  // second lowest byte of EAX
- 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 "";
- 18   }
- 19 }
- 20 
- 21 uint8_t* effective_byte_address(uint8_t modrm) {
- 22   uint8_t mod = (modrm>>6);
- 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();
- 27     return reg_8bit(rm);
- 28   }
- 29   // the rest is as usual
- 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
- 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");
- 42 
- 43 :(code)
- 44 void test_copy_r8_to_mem_at_r32() {
- 45   Reg[EBX].i = 0x224488ab;
- 46   Reg[EAX].i = 0x2000;
- 47   run(
- 48       "== code 0x1\n"
- 49       // op     ModR/M  SIB   displacement  immediate
- 50       "  88     18                                      \n"  // copy BL to the byte at *EAX
- 51       // ModR/M in binary: 00 (indirect mode) 011 (src BL) 000 (dest EAX)
- 52       "== data 0x2000\n"
- 53       "f0 cc bb aa\n"
- 54   );
- 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));
- 61 }
- 62 
- 63 :(before "End Single-Byte Opcodes")
- 64 case 0x88: {  // copy r8 to r/m8
- 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();
- 68   // use unsigned to zero-extend 8-bit value to 32 bits
- 69   uint8_t* dest = reinterpret_cast<uint8_t*>(effective_byte_address(modrm));
- 70   const uint8_t* src = reg_8bit(rsrc);
- 71   *dest = *src;
- 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");
- 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;
- 85   run(
- 86       "== code 0x1\n"
- 87       // op     ModR/M  SIB   displacement  immediate
- 88       "  8a     18                                      \n"  // copy just the byte at *EAX to BL
- 89       // ModR/M in binary: 00 (indirect mode) 011 (dest EBX) 000 (src EAX)
- 90       "== data 0x2000\n"
- 91       "ab ff ff ff\n"  // 0xab with more data in following bytes
- 92   );
- 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"
- 97       // remaining bytes of EBX are *not* cleared
- 98       "run: EBX now contains 0xaabbccab\n"
- 99   );
-100 }
-101 
-102 :(before "End Single-Byte Opcodes")
-103 case 0x8a: {  // copy r/m8 to r8
-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();
-107   // use unsigned to zero-extend 8-bit value to 32 bits
-108   const uint8_t* src = reinterpret_cast<uint8_t*>(effective_byte_address(modrm));
-109   uint8_t* dest = reg_8bit(rdest);
-110   trace(Callstack_depth+1, "run") << "storing 0x" << HEXBYTE << NUM(*src) << end();
-111   *dest = *src;
-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();
-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;
-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(
-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);
-134 }
-135 
-136 //:
-137 
-138 :(before "End Initialize Op Names")
-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;
-144   run(
-145       "== code 0x1\n"
-146       // op     ModR/M  SIB   displacement  immediate
-147       "  c6     00                          dd          \n"  // copy to the byte at *EAX
-148       // ModR/M in binary: 00 (indirect mode) 000 (unused) 000 (dest EAX)
-149       "== data 0x2000\n"
-150       "f0 cc bb aa\n"
-151   );
-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));
-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();
-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";
-169     exit(1);
-170   }
-171   // use unsigned to zero-extend 8-bit value to 32 bits
-172   uint8_t* dest = reinterpret_cast<uint8_t*>(effective_byte_address(modrm));
-173   *dest = src;
-174   trace(Callstack_depth+1, "run") << "storing 0x" << HEXBYTE << NUM(*dest) << end();
-175   break;
-176 }
-
- - - -- cgit 1.4.1-2-gfad0