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/016index_addressing.cc.html | 217 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 html/016index_addressing.cc.html (limited to 'html/016index_addressing.cc.html') diff --git a/html/016index_addressing.cc.html b/html/016index_addressing.cc.html new file mode 100644 index 00000000..bd2304e9 --- /dev/null +++ b/html/016index_addressing.cc.html @@ -0,0 +1,217 @@ + + + + +Mu - subx/016index_addressing.cc + + + + + + + + + + +https://github.com/akkartik/mu/blob/master/subx/016index_addressing.cc +
+  1 //: operating on memory at the address provided by some register plus optional scale and offset
+  2 
+  3 :(code)
+  4 void test_add_r32_to_mem_at_r32_with_sib() {
+  5   Reg[EBX].i = 0x10;
+  6   Reg[EAX].i = 0x2000;
+  7   run(
+  8       "== code 0x1\n"
+  9       // op     ModR/M  SIB   displacement  immediate
+ 10       "  01     1c      20                              \n"  // add EBX to *EAX
+ 11       // ModR/M in binary: 00 (indirect mode) 011 (src EBX) 100 (dest in SIB)
+ 12       // SIB in binary: 00 (scale 1) 100 (no index) 000 (base EAX)
+ 13       "== data 0x2000\n"
+ 14       "01 00 00 00\n"  // 0x00000001
+ 15   );
+ 16   CHECK_TRACE_CONTENTS(
+ 17       "run: add EBX to r/m32\n"
+ 18       "run: effective address is initially 0x00002000 (EAX)\n"
+ 19       "run: effective address is 0x00002000\n"
+ 20       "run: storing 0x00000011\n"
+ 21   );
+ 22 }
+ 23 
+ 24 :(before "End Mod 0 Special-cases(addr)")
+ 25 case 4:  // exception: mod 0b00 rm 0b100 => incoming SIB (scale-index-base) byte
+ 26   addr = effective_address_from_sib(mod);
+ 27   break;
+ 28 :(code)
+ 29 uint32_t effective_address_from_sib(uint8_t mod) {
+ 30   const uint8_t sib = next();
+ 31   const uint8_t base = sib&0x7;
+ 32   uint32_t addr = 0;
+ 33   if (base != EBP || mod != 0) {
+ 34     addr = Reg[base].u;
+ 35     trace(Callstack_depth+1, "run") << "effective address is initially 0x" << HEXWORD << addr << " (" << rname(base) << ")" << end();
+ 36   }
+ 37   else {
+ 38     // base == EBP && mod == 0
+ 39     addr = next32();  // ignore base
+ 40     trace(Callstack_depth+1, "run") << "effective address is initially 0x" << HEXWORD << addr << " (disp32)" << end();
+ 41   }
+ 42   const uint8_t index = (sib>>3)&0x7;
+ 43   if (index == ESP) {
+ 44     // ignore index and scale
+ 45     trace(Callstack_depth+1, "run") << "effective address is 0x" << HEXWORD << addr << end();
+ 46   }
+ 47   else {
+ 48     const uint8_t scale = (1 << (sib>>6));
+ 49     addr += Reg[index].i*scale;  // treat index register as signed. Maybe base as well? But we'll always ensure it's non-negative.
+ 50     trace(Callstack_depth+1, "run") << "effective address is 0x" << HEXWORD << addr << " (after adding " << rname(index) << "*" << NUM(scale) << ")" << end();
+ 51   }
+ 52   return addr;
+ 53 }
+ 54 
+ 55 :(code)
+ 56 void test_add_r32_to_mem_at_base_r32_index_r32() {
+ 57   Reg[EBX].i = 0x10;  // source
+ 58   Reg[EAX].i = 0x1ffe;  // dest base
+ 59   Reg[ECX].i = 0x2;  // dest index
+ 60   run(
+ 61       "== code 0x1\n"
+ 62       // op     ModR/M  SIB   displacement  immediate
+ 63       "  01     1c      08                              \n"  // add EBX to *(EAX+ECX)
+ 64       // ModR/M in binary: 00 (indirect mode) 011 (src EBX) 100 (dest in SIB)
+ 65       // SIB in binary: 00 (scale 1) 001 (index ECX) 000 (base EAX)
+ 66       "== data 0x2000\n"
+ 67       "01 00 00 00\n"  // 0x00000001
+ 68   );
+ 69   CHECK_TRACE_CONTENTS(
+ 70       "run: add EBX to r/m32\n"
+ 71       "run: effective address is initially 0x00001ffe (EAX)\n"
+ 72       "run: effective address is 0x00002000 (after adding ECX*1)\n"
+ 73       "run: storing 0x00000011\n"
+ 74   );
+ 75 }
+ 76 
+ 77 :(code)
+ 78 void test_add_r32_to_mem_at_displacement_using_sib() {
+ 79   Reg[EBX].i = 0x10;  // source
+ 80   run(
+ 81       "== code 0x1\n"
+ 82       // op     ModR/M  SIB   displacement  immediate
+ 83       "  01     1c      25    00 20 00 00               \n"  // add EBX to *0x2000
+ 84       // ModR/M in binary: 00 (indirect mode) 011 (src EBX) 100 (dest in SIB)
+ 85       // SIB in binary: 00 (scale 1) 100 (no index) 101 (not EBP but disp32)
+ 86       "== data 0x2000\n"
+ 87       "01 00 00 00\n"  // 0x00000001
+ 88   );
+ 89   CHECK_TRACE_CONTENTS(
+ 90       "run: add EBX to r/m32\n"
+ 91       "run: effective address is initially 0x00002000 (disp32)\n"
+ 92       "run: effective address is 0x00002000\n"
+ 93       "run: storing 0x00000011\n"
+ 94   );
+ 95 }
+ 96 
+ 97 //:
+ 98 
+ 99 :(code)
+100 void test_add_r32_to_mem_at_base_r32_index_r32_plus_disp8() {
+101   Reg[EBX].i = 0x10;  // source
+102   Reg[EAX].i = 0x1ff9;  // dest base
+103   Reg[ECX].i = 0x5;  // dest index
+104   run(
+105       "== code 0x1\n"
+106       // op     ModR/M  SIB   displacement  immediate
+107       "  01     5c      08    02                        \n"  // add EBX to *(EAX+ECX+2)
+108       // ModR/M in binary: 01 (indirect+disp8 mode) 011 (src EBX) 100 (dest in SIB)
+109       // SIB in binary: 00 (scale 1) 001 (index ECX) 000 (base EAX)
+110       "== data 0x2000\n"
+111       "01 00 00 00\n"  // 0x00000001
+112   );
+113   CHECK_TRACE_CONTENTS(
+114       "run: add EBX to r/m32\n"
+115       "run: effective address is initially 0x00001ff9 (EAX)\n"
+116       "run: effective address is 0x00001ffe (after adding ECX*1)\n"
+117       "run: effective address is 0x00002000 (after adding disp8)\n"
+118       "run: storing 0x00000011\n"
+119   );
+120 }
+121 
+122 :(before "End Mod 1 Special-cases(addr)")
+123 case 4:  // exception: mod 0b01 rm 0b100 => incoming SIB (scale-index-base) byte
+124   addr = effective_address_from_sib(mod);
+125   break;
+126 
+127 //:
+128 
+129 :(code)
+130 void test_add_r32_to_mem_at_base_r32_index_r32_plus_disp32() {
+131   Reg[EBX].i = 0x10;  // source
+132   Reg[EAX].i = 0x1ff9;  // dest base
+133   Reg[ECX].i = 0x5;  // dest index
+134   run(
+135       "== code 0x1\n"
+136       // op     ModR/M  SIB   displacement  immediate
+137       "  01     9c      08    02 00 00 00               \n"  // add EBX to *(EAX+ECX+2)
+138       // ModR/M in binary: 10 (indirect+disp32 mode) 011 (src EBX) 100 (dest in SIB)
+139       // SIB in binary: 00 (scale 1) 001 (index ECX) 000 (base EAX)
+140       "== data 0x2000\n"
+141       "01 00 00 00\n"  // 0x00000001
+142   );
+143   CHECK_TRACE_CONTENTS(
+144       "run: add EBX to r/m32\n"
+145       "run: effective address is initially 0x00001ff9 (EAX)\n"
+146       "run: effective address is 0x00001ffe (after adding ECX*1)\n"
+147       "run: effective address is 0x00002000 (after adding disp32)\n"
+148       "run: storing 0x00000011\n"
+149   );
+150 }
+151 
+152 :(before "End Mod 2 Special-cases(addr)")
+153 case 4:  // exception: mod 0b10 rm 0b100 => incoming SIB (scale-index-base) byte
+154   addr = effective_address_from_sib(mod);
+155   break;
+
+ + + -- cgit 1.4.1-2-gfad0