https://github.com/akkartik/mu/blob/master/subx/016index_addressing.cc
1
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
10 " 01 1c 20 \n"
11
12
13 "== data 0x2000\n"
14 "01 00 00 00\n"
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:
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
39 addr = next32();
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
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;
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;
58 Reg[EAX].i = 0x1ffe;
59 Reg[ECX].i = 0x2;
60 run(
61 "== code 0x1\n"
62
63 " 01 1c 08 \n"
64
65
66 "== data 0x2000\n"
67 "01 00 00 00\n"
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;
80 run(
81 "== code 0x1\n"
82
83 " 01 1c 25 00 20 00 00 \n"
84
85
86 "== data 0x2000\n"
87 "01 00 00 00\n"
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;
102 Reg[EAX].i = 0x1ff9;
103 Reg[ECX].i = 0x5;
104 run(
105 "== code 0x1\n"
106
107 " 01 5c 08 02 \n"
108
109
110 "== data 0x2000\n"
111 "01 00 00 00\n"
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:
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;
132 Reg[EAX].i = 0x1ff9;
133 Reg[ECX].i = 0x5;
134 run(
135 "== code 0x1\n"
136
137 " 01 9c 08 02 00 00 00 \n"
138
139
140 "== data 0x2000\n"
141 "01 00 00 00\n"
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:
154 addr = effective_address_from_sib(mod);
155 break;