https://github.com/akkartik/mu/blob/master/subx/016index_addressing.cc
1
2
3 :(scenario add_r32_to_mem_at_r32_with_sib)
4 % Reg[EBX].i = 0x10;
5 % Reg[EAX].i = 0x2000;
6 == 0x1
7
8 01 1c 20
9
10
11 == 0x2000
12 01 00 00 00
13 +run: add EBX to r/m32
14 +run: effective address is initially 0x00002000 (EAX)
15 +run: effective address is 0x00002000
16 +run: storing 0x00000011
17
18 :(before "End Mod 0 Special-cases(addr)")
19 case 4:
20 addr = effective_address_from_sib(mod);
21 break;
22 :(code)
23 uint32_t effective_address_from_sib(uint8_t mod) {
24 const uint8_t sib = next();
25 const uint8_t base = sib&0x7;
26 uint32_t addr = 0;
27 if (base != EBP || mod != 0) {
28 addr = Reg[base].u;
29 trace(Callstack_depth+1, "run") << "effective address is initially 0x" << HEXWORD << addr << " (" << rname(base) << ")" << end();
30 }
31 else {
32
33 addr = next32();
34 trace(Callstack_depth+1, "run") << "effective address is initially 0x" << HEXWORD << addr << " (disp32)" << end();
35 }
36 const uint8_t index = (sib>>3)&0x7;
37 if (index == ESP) {
38
39 trace(Callstack_depth+1, "run") << "effective address is 0x" << HEXWORD << addr << end();
40 }
41 else {
42 const uint8_t scale = (1 << (sib>>6));
43 addr += Reg[index].i*scale;
44 trace(Callstack_depth+1, "run") << "effective address is 0x" << HEXWORD << addr << " (after adding " << rname(index) << "*" << NUM(scale) << ")" << end();
45 }
46 return addr;
47 }
48
49 :(scenario add_r32_to_mem_at_base_r32_index_r32)
50 % Reg[EBX].i = 0x10; // source
51 % Reg[EAX].i = 0x1ffe; // dest base
52 % Reg[ECX].i = 0x2; // dest index
53 == 0x1
54
55 01 1c 08
56
57
58 == 0x2000
59 01 00 00 00
60 +run: add EBX to r/m32
61 +run: effective address is initially 0x00001ffe (EAX)
62 +run: effective address is 0x00002000 (after adding ECX*1)
63 +run: storing 0x00000011
64
65 :(scenario add_r32_to_mem_at_displacement_using_sib)
66 % Reg[EBX].i = 0x10; // source
67 == 0x1
68
69 01 1c 25 00 20 00 00
70
71
72 == 0x2000
73 01 00 00 00
74 +run: add EBX to r/m32
75 +run: effective address is initially 0x00002000 (disp32)
76 +run: effective address is 0x00002000
77 +run: storing 0x00000011
78
79
80
81 :(scenario add_r32_to_mem_at_base_r32_index_r32_plus_disp8)
82 % Reg[EBX].i = 0x10; // source
83 % Reg[EAX].i = 0x1ff9; // dest base
84 % Reg[ECX].i = 0x5; // dest index
85 == 0x1
86
87 01 5c 08 02
88
89
90 == 0x2000
91 01 00 00 00
92 +run: add EBX to r/m32
93 +run: effective address is initially 0x00001ff9 (EAX)
94 +run: effective address is 0x00001ffe (after adding ECX*1)
95 +run: effective address is 0x00002000 (after adding disp8)
96 +run: storing 0x00000011
97
98 :(before "End Mod 1 Special-cases(addr)")
99 case 4:
100 addr = effective_address_from_sib(mod);
101 break;
102
103
104
105 :(scenario add_r32_to_mem_at_base_r32_index_r32_plus_disp32)
106 % Reg[EBX].i = 0x10; // source
107 % Reg[EAX].i = 0x1ff9; // dest base
108 % Reg[ECX].i = 0x5; // dest index
109 == 0x1
110
111 01 9c 08 02 00 00 00
112
113
114 == 0x2000
115 01 00 00 00
116 +run: add EBX to r/m32
117 +run: effective address is initially 0x00001ff9 (EAX)
118 +run: effective address is 0x00001ffe (after adding ECX*1)
119 +run: effective address is 0x00002000 (after adding disp32)
120 +run: storing 0x00000011
121
122 :(before "End Mod 2 Special-cases(addr)")
123 case 4:
124 addr = effective_address_from_sib(mod);
125 break;