1
2
3 :(scenario add_imm32_to_r32)
4 % Reg[3].i = 1;
5
6 81 c3 0a 0b 0c 0d
7 +run: combine imm32 0x0d0c0b0a with effective address
8 +run: effective address is reg 3
9 +run: subop add
10 +run: storing 0x0d0c0b0b
11
12 :(before "End Single-Byte Opcodes")
13 case 0x81: {
14 uint8_t modrm = next();
15 int32_t arg2 = imm32();
16 trace(2, "run") << "combine imm32 0x" << HEXWORD << arg2 << " with effective address" << end();
17 int32_t* arg1 = effective_address(modrm);
18 uint8_t subop = (modrm>>3)&0x7;
19 switch (subop) {
20 case 0:
21 ¦ trace(2, "run") << "subop add" << end();
22 ¦ BINARY_ARITHMETIC_OP(+, *arg1, arg2);
23 ¦ break;
24
25 default:
26 ¦ cerr << "unrecognized sub-opcode after 81: " << NUM(subop) << '\n';
27 ¦ exit(1);
28 }
29 break;
30 }
31
32
33
34 :(scenario add_imm32_to_mem_at_r32)
35 % Reg[3].i = 0x60;
36 % Mem.at(0x60) = 1;
37
38 81 03 0a 0b 0c 0d
39 +run: combine imm32 0x0d0c0b0a with effective address
40 +run: effective address is mem at address 0x60 (reg 3)
41 +run: subop add
42 +run: storing 0x0d0c0b0b
43
44
45
46 :(scenario subtract_imm32_from_eax)
47 % Reg[EAX].i = 0x0d0c0baa;
48
49 2d 0a 0b 0c 0d
50 +run: subtract imm32 0x0d0c0b0a from reg EAX
51 +run: storing 0x000000a0
52
53 :(before "End Single-Byte Opcodes")
54 case 0x2d: {
55 int32_t arg2 = imm32();
56 trace(2, "run") << "subtract imm32 0x" << HEXWORD << arg2 << " from reg EAX" << end();
57 BINARY_ARITHMETIC_OP(-, Reg[EAX].i, arg2);
58 break;
59 }
60
61
62
63 :(scenario subtract_imm32_from_mem_at_r32)
64 % Reg[3].i = 0x60;
65 % Mem.at(0x60) = 10;
66
67 81 2b 01 00 00 00
68 +run: combine imm32 0x00000001 with effective address
69 +run: effective address is mem at address 0x60 (reg 3)
70 +run: subop subtract
71 +run: storing 0x00000009
72
73
74
75 :(scenario subtract_imm32_from_r32)
76 % Reg[3].i = 10;
77
78 81 eb 01 00 00 00
79 +run: combine imm32 0x00000001 with effective address
80 +run: effective address is reg 3
81 +run: subop subtract
82 +run: storing 0x00000009
83
84 :(before "End Op 81 Subops")
85 case 5: {
86 trace(2, "run") << "subop subtract" << end();
87 BINARY_ARITHMETIC_OP(-, *arg1, arg2);
88 break;
89 }
90
91
92
93 :(scenario and_imm32_with_eax)
94 % Reg[EAX].i = 0xff;
95
96 25 0a 0b 0c 0d
97 +run: and imm32 0x0d0c0b0a with reg EAX
98 +run: storing 0x0000000a
99
100 :(before "End Single-Byte Opcodes")
101 case 0x25: {
102 int32_t arg2 = imm32();
103 trace(2, "run") << "and imm32 0x" << HEXWORD << arg2 << " with reg EAX" << end();
104 BINARY_BITWISE_OP(&, Reg[EAX].i, arg2);
105 break;
106 }
107
108
109
110 :(scenario and_imm32_with_mem_at_r32)
111 % Reg[3].i = 0x60;
112 % Mem.at(0x60) = 0xff;
113
114 81 23 0a 0b 0c 0d
115 +run: combine imm32 0x0d0c0b0a with effective address
116 +run: effective address is mem at address 0x60 (reg 3)
117 +run: subop and
118 +run: storing 0x0000000a
119
120
121
122 :(scenario and_imm32_with_r32)
123 % Reg[3].i = 0xff;
124
125 81 e3 0a 0b 0c 0d
126 +run: combine imm32 0x0d0c0b0a with effective address
127 +run: effective address is reg 3
128 +run: subop and
129 +run: storing 0x0000000a
130
131 :(before "End Op 81 Subops")
132 case 4: {
133 trace(2, "run") << "subop and" << end();
134 BINARY_BITWISE_OP(&, *arg1, arg2);
135 break;
136 }
137
138
139
140 :(scenario or_imm32_with_eax)
141 % Reg[EAX].i = 0xd0c0b0a0;
142
143 0d 0a 0b 0c 0d
144 +run: or imm32 0x0d0c0b0a with reg EAX
145 +run: storing 0xddccbbaa
146
147 :(before "End Single-Byte Opcodes")
148 case 0x0d: {
149 int32_t arg2 = imm32();
150 trace(2, "run") << "or imm32 0x" << HEXWORD << arg2 << " with reg EAX" << end();
151 BINARY_BITWISE_OP(|, Reg[EAX].i, arg2);
152 break;
153 }
154
155
156
157 :(scenario or_imm32_with_mem_at_r32)
158 % Reg[3].i = 0x60;
159 % Mem.at(0x60) = 0xa0;
160 % Mem.at(0x61) = 0xb0;
161 % Mem.at(0x62) = 0xc0;
162 % Mem.at(0x63) = 0xd0;
163
164 81 0b 0a 0b 0c 0d
165 +run: combine imm32 0x0d0c0b0a with effective address
166 +run: effective address is mem at address 0x60 (reg 3)
167 +run: subop or
168 +run: storing 0xddccbbaa
169
170
171
172 :(scenario or_imm32_with_r32)
173 % Reg[3].i = 0xd0c0b0a0;
174
175 81 cb 0a 0b 0c 0d
176 +run: combine imm32 0x0d0c0b0a with effective address
177 +run: effective address is reg 3
178 +run: subop or
179 +run: storing 0xddccbbaa
180
181 :(before "End Op 81 Subops")
182 case 1: {
183 trace(2, "run") << "subop or" << end();
184 BINARY_BITWISE_OP(|, *arg1, arg2);
185 break;
186 }
187
188
189
190 :(scenario xor_imm32_with_eax)
191 % Reg[EAX].i = 0xddccb0a0;
192
193 35 0a 0b 0c 0d
194 +run: xor imm32 0x0d0c0b0a with reg EAX
195 +run: storing 0xd0c0bbaa
196
197 :(before "End Single-Byte Opcodes")
198 case 0x35: {
199 int32_t arg2 = imm32();
200 trace(2, "run") << "xor imm32 0x" << HEXWORD << arg2 << " with reg EAX" << end();
201 BINARY_BITWISE_OP(^, Reg[EAX].i, arg2);
202 break;
203 }
204
205
206
207 :(scenario xor_imm32_with_mem_at_r32)
208 % Reg[3].i = 0x60;
209 % Mem.at(0x60) = 0xa0;
210 % Mem.at(0x61) = 0xb0;
211 % Mem.at(0x62) = 0xc0;
212 % Mem.at(0x63) = 0xd0;
213
214 81 33 0a 0b 0c 0d
215 +run: combine imm32 0x0d0c0b0a with effective address
216 +run: effective address is mem at address 0x60 (reg 3)
217 +run: subop xor
218 +run: storing 0xddccbbaa
219
220
221
222 :(scenario xor_imm32_with_r32)
223 % Reg[3].i = 0xd0c0b0a0;
224
225 81 f3 0a 0b 0c 0d
226 +run: combine imm32 0x0d0c0b0a with effective address
227 +run: effective address is reg 3
228 +run: subop xor
229 +run: storing 0xddccbbaa
230
231 :(before "End Op 81 Subops")
232 case 6: {
233 trace(2, "run") << "subop xor" << end();
234 BINARY_BITWISE_OP(^, *arg1, arg2);
235 break;
236 }