https://github.com/akkartik/mu/blob/master/subx/018jump_disp32.cc
1
2
3
4
5 :(before "End Initialize Op Names")
6 put_new(Name, "e9", "jump disp32 bytes away (jmp)");
7
8 :(code)
9 void test_jump_disp32() {
10 run(
11 "== code 0x1\n"
12
13 " e9 05 00 00 00 \n"
14 " 05 00 00 00 01 \n"
15 " 05 00 00 00 02 \n"
16 );
17 CHECK_TRACE_CONTENTS(
18 "run: 0x00000001 opcode: e9\n"
19 "run: jump 5\n"
20 "run: 0x0000000b opcode: 05\n"
21 );
22 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000006 opcode: 05");
23 }
24
25 :(before "End Single-Byte Opcodes")
26 case 0xe9: {
27 const int32_t offset = next32();
28 trace(Callstack_depth+1, "run") << "jump " << offset << end();
29 EIP += offset;
30 break;
31 }
32
33
34
35 :(before "End Initialize Op Names")
36 put_new(Name_0f, "84", "jump disp32 bytes away if equal, if ZF is set (jcc/jz/je)");
37
38 :(code)
39 void test_je_disp32_success() {
40 ZF = true;
41 run(
42 "== code 0x1\n"
43
44 " 0f 84 05 00 00 00 \n"
45 " 05 00 00 00 01 \n"
46 " 05 00 00 00 02 \n"
47 );
48 CHECK_TRACE_CONTENTS(
49 "run: 0x00000001 opcode: 0f\n"
50 "run: jump 5\n"
51 "run: 0x0000000c opcode: 05\n"
52 );
53 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05");
54 }
55
56 :(before "End Two-Byte Opcodes Starting With 0f")
57 case 0x84: {
58 const int32_t offset = next32();
59 if (ZF) {
60 trace(Callstack_depth+1, "run") << "jump " << NUM(offset) << end();
61 EIP += offset;
62 }
63 break;
64 }
65
66 :(code)
67 void test_je_disp32_fail() {
68 ZF = false;
69 run(
70 "== code 0x1\n"
71
72 " 0f 84 05 00 00 00 \n"
73 " 05 00 00 00 01 \n"
74 " 05 00 00 00 02 \n"
75 );
76 CHECK_TRACE_CONTENTS(
77 "run: 0x00000001 opcode: 0f\n"
78 "run: 0x00000007 opcode: 05\n"
79 "run: 0x0000000c opcode: 05\n"
80 );
81 CHECK_TRACE_DOESNT_CONTAIN("run: jump 5");
82 }
83
84
85
86 :(before "End Initialize Op Names")
87 put_new(Name_0f, "85", "jump disp32 bytes away if not equal, if ZF is not set (jcc/jnz/jne)");
88
89 :(code)
90 void test_jne_disp32_success() {
91 ZF = false;
92 run(
93 "== code 0x1\n"
94
95 " 0f 85 05 00 00 00 \n"
96 " 05 00 00 00 01 \n"
97 " 05 00 00 00 02 \n"
98 );
99 CHECK_TRACE_CONTENTS(
100 "run: 0x00000001 opcode: 0f\n"
101 "run: jump 5\n"
102 "run: 0x0000000c opcode: 05\n"
103 );
104 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05");
105 }
106
107 :(before "End Two-Byte Opcodes Starting With 0f")
108 case 0x85: {
109 const int32_t offset = next32();
110 if (!ZF) {
111 trace(Callstack_depth+1, "run") << "jump " << NUM(offset) << end();
112 EIP += offset;
113 }
114 break;
115 }
116
117 :(code)
118 void test_jne_disp32_fail() {
119 ZF = true;
120 run(
121 "== code 0x1\n"
122
123 " 0f 85 05 00 00 00 \n"
124 " 05 00 00 00 01 \n"
125 " 05 00 00 00 02 \n"
126 );
127 CHECK_TRACE_CONTENTS(
128 "run: 0x00000001 opcode: 0f\n"
129 "run: 0x00000007 opcode: 05\n"
130 "run: 0x0000000c opcode: 05\n"
131 );
132 CHECK_TRACE_DOESNT_CONTAIN("run: jump 5");
133 }
134
135
136
137 :(before "End Initialize Op Names")
138 put_new(Name_0f, "8f", "jump disp32 bytes away if greater, if ZF is unset and SF == OF (jcc/jg/jnle)");
139
140 :(code)
141 void test_jg_disp32_success() {
142 ZF = false;
143 SF = false;
144 OF = false;
145 run(
146 "== code 0x1\n"
147
148 " 0f 8f 05 00 00 00 \n"
149 " 05 00 00 00 01 \n"
150 " 05 00 00 00 02 \n"
151 );
152 CHECK_TRACE_CONTENTS(
153 "run: 0x00000001 opcode: 0f\n"
154 "run: jump 5\n"
155 "run: 0x0000000c opcode: 05\n"
156 );
157 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05");
158 }
159
160 :(before "End Two-Byte Opcodes Starting With 0f")
161 case 0x8f: {
162 const int32_t offset = next32();
163 if (!ZF && SF == OF) {
164 trace(Callstack_depth+1, "run") << "jump " << NUM(offset) << end();
165 EIP += offset;
166 }
167 break;
168 }
169
170 :(code)
171 void test_jg_disp32_fail() {
172 ZF = false;
173 SF = true;
174 OF = false;
175 run(
176 "== code 0x1\n"
177
178 " 0f 8f 05 00 00 00 \n"
179 " 05 00 00 00 01 \n"
180 " 05 00 00 00 02 \n"
181 );
182 CHECK_TRACE_CONTENTS(
183 "run: 0x00000001 opcode: 0f\n"
184 "run: 0x00000007 opcode: 05\n"
185 "run: 0x0000000c opcode: 05\n"
186 );
187 CHECK_TRACE_DOESNT_CONTAIN("run: jump 5");
188 }
189
190
191
192 :(before "End Initialize Op Names")
193 put_new(Name_0f, "8d", "jump disp32 bytes away if greater or equal, if SF == OF (jcc/jge/jnl)");
194
195 :(code)
196 void test_jge_disp32_success() {
197 SF = false;
198 OF = false;
199 run(
200 "== code 0x1\n"
201
202 " 0f 8d 05 00 00 00 \n"
203 " 05 00 00 00 01 \n"
204 " 05 00 00 00 02 \n"
205 );
206 CHECK_TRACE_CONTENTS(
207 "run: 0x00000001 opcode: 0f\n"
208 "run: jump 5\n"
209 "run: 0x0000000c opcode: 05\n"
210 );
211 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05");
212 }
213
214 :(before "End Two-Byte Opcodes Starting With 0f")
215 case 0x8d: {
216 const int32_t offset = next32();
217 if (SF == OF) {
218 trace(Callstack_depth+1, "run") << "jump " << NUM(offset) << end();
219 EIP += offset;
220 }
221 break;
222 }
223
224 :(code)
225 void test_jge_disp32_fail() {
226 SF = true;
227 OF = false;
228 run(
229 "== code 0x1\n"
230
231 " 0f 8d 05 00 00 00 \n"
232 " 05 00 00 00 01 \n"
233 " 05 00 00 00 02 \n"
234 );
235 CHECK_TRACE_CONTENTS(
236 "run: 0x00000001 opcode: 0f\n"
237 "run: 0x00000007 opcode: 05\n"
238 "run: 0x0000000c opcode: 05\n"
239 );
240 CHECK_TRACE_DOESNT_CONTAIN("run: jump 5");
241 }
242
243
244
245 :(before "End Initialize Op Names")
246 put_new(Name_0f, "8c", "jump disp32 bytes away if lesser, if SF != OF (jcc/jl/jnge)");
247
248 :(code)
249 void test_jl_disp32_success() {
250 ZF = false;
251 SF = true;
252 OF = false;
253 run(
254 "== code 0x1\n"
255
256 " 0f 8c 05 00 00 00 \n"
257 " 05 00 00 00 01 \n"
258 " 05 00 00 00 02 \n"
259 );
260 CHECK_TRACE_CONTENTS(
261 "run: 0x00000001 opcode: 0f\n"
262 "run: jump 5\n"
263 "run: 0x0000000c opcode: 05\n"
264 );
265 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05");
266 }
267
268 :(before "End Two-Byte Opcodes Starting With 0f")
269 case 0x8c: {
270 const int32_t offset = next32();
271 if (SF != OF) {
272 trace(Callstack_depth+1, "run") << "jump " << NUM(offset) << end();
273 EIP += offset;
274 }
275 break;
276 }
277
278 :(code)
279 void test_jl_disp32_fail() {
280 ZF = false;
281 SF = false;
282 OF = false;
283 run(
284 "== code 0x1\n"
285
286 " 0f 8c 05 00 00 00 \n"
287 " 05 00 00 00 01 \n"
288 " 05 00 00 00 02 \n"
289 );
290 CHECK_TRACE_CONTENTS(
291 "run: 0x00000001 opcode: 0f\n"
292 "run: 0x00000007 opcode: 05\n"
293 "run: 0x0000000c opcode: 05\n"
294 );
295 CHECK_TRACE_DOESNT_CONTAIN("run: jump 5");
296 }
297
298
299
300 :(before "End Initialize Op Names")
301 put_new(Name_0f, "8e", "jump disp32 bytes away if lesser or equal, if ZF is set or SF != OF (jcc/jle/jng)");
302
303 :(code)
304 void test_jle_disp32_equal() {
305 ZF = true;
306 SF = false;
307 OF = false;
308 run(
309 "== code 0x1\n"
310
311 " 0f 8e 05 00 00 00 \n"
312 " 05 00 00 00 01 \n"
313 " 05 00 00 00 02 \n"
314 );
315 CHECK_TRACE_CONTENTS(
316 "run: 0x00000001 opcode: 0f\n"
317 "run: jump 5\n"
318 "run: 0x0000000c opcode: 05\n"
319 );
320 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05");
321 }
322
323 :(code)
324 void test_jle_disp32_lesser() {
325 ZF = false;
326 SF = true;
327 OF = false;
328 run(
329 "== code 0x1\n"
330
331 " 0f 8e 05 00 00 00 \n"
332 " 05 00 00 00 01 \n"
333 " 05 00 00 00 02 \n"
334 );
335 CHECK_TRACE_CONTENTS(
336 "run: 0x00000001 opcode: 0f\n"
337 "run: jump 5\n"
338 "run: 0x0000000c opcode: 05\n"
339 );
340 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05");
341 }
342
343 :(before "End Two-Byte Opcodes Starting With 0f")
344 case 0x8e: {
345 const int32_t offset = next32();
346 if (ZF || SF != OF) {
347 trace(Callstack_depth+1, "run") << "jump " << NUM(offset) << end();
348 EIP += offset;
349 }
350 break;
351 }
352
353 :(code)
354 void test_jle_disp32_greater() {
355 ZF = false;
356 SF = false;
357 OF = false;
358 run(
359 "== code 0x1\n"
360
361 " 0f 8e 05 00 00 00 \n"
362 " 05 00 00 00 01 \n"
363 " 05 00 00 00 02 \n"
364 );
365 CHECK_TRACE_CONTENTS(
366 "run: 0x00000001 opcode: 0f\n"
367 "run: 0x00000007 opcode: 05\n"
368 "run: 0x0000000c opcode: 05\n"
369 );
370 CHECK_TRACE_DOESNT_CONTAIN("run: jump 5");
371 }