https://github.com/akkartik/mu/blob/master/subx/018jump_disp32.cc
  1 //: jump to 32-bit offset
  2 
  3 //:: jump
  4 
  5 :(before "End Initialize Op Names")
  6 put_new(Name, "e9", "jump disp32 bytes away (jmp)");
  7 
  8 :(scenario jump_disp32)
  9 == 0x1
 10 # op  ModR/M  SIB   displacement  immediate
 11   e9                05 00 00 00               # skip 1 instruction
 12   05                              00 00 00 01
 13   05                              00 00 00 02
 14 +run: 0x00000001 opcode: e9
 15 +run: jump 5
 16 +run: 0x0000000b opcode: 05
 17 -run: 0x00000006 opcode: 05
 18 
 19 :(before "End Single-Byte Opcodes")
 20 case 0xe9: {  // jump disp32
 21   const int32_t offset = next32();
 22   trace(Callstack_depth+1, "run") << "jump " << offset << end();
 23   EIP += offset;
 24   break;
 25 }
 26 
 27 //:: jump if equal/zero
 28 
 29 :(before "End Initialize Op Names")
 30 put_new(Name_0f, "84", "jump disp32 bytes away if equal, if ZF is set (jcc/jz/je)");
 31 
 32 :(scenario je_disp32_success)
 33 % ZF = true;
 34 == 0x1
 35 # op      ModR/M  SIB   displacement  immediate
 36   0f 84                 05 00 00 00               # skip 1 instruction
 37   05                                  00 00 00 01
 38   05                                  00 00 00 02
 39 +run: 0x00000001 opcode: 0f
 40 +run: jump 5
 41 +run: 0x0000000c opcode: 05
 42 -run: 0x00000007 opcode: 05
 43 
 44 :(before "End Two-Byte Opcodes Starting With 0f")
 45 case 0x84: {  // jump disp32 if ZF
 46   const int32_t offset = next32();
 47   if (ZF) {
 48     trace(Callstack_depth+1, "run") << "jump " << NUM(offset) << end();
 49     EIP += offset;
 50   }
 51   break;
 52 }
 53 
 54 :(scenario je_disp32_fail)
 55 % ZF = false;
 56 == 0x1
 57 # op      ModR/M  SIB   displacement  immediate
 58   0f 84                 05 00 00 00               # skip 1 instruction
 59   05                                  00 00 00 01
 60   05                                  00 00 00 02
 61 +run: 0x00000001 opcode: 0f
 62 +run: 0x00000007 opcode: 05
 63 +run: 0x0000000c opcode: 05
 64 -run: jump 5
 65 
 66 //:: jump if not equal/not zero
 67 
 68 :(before "End Initialize Op Names")
 69 put_new(Name_0f, "85", "jump disp32 bytes away if not equal, if ZF is not set (jcc/jnz/jne)");
 70 
 71 :(scenario jne_disp32_success)
 72 % ZF = false;
 73 == 0x1
 74 # op      ModR/M  SIB   displacement  immediate
 75   0f 85                 05 00 00 00               # skip 1 instruction
 76   05                                  00 00 00 01
 77   05                                  00 00 00 02
 78 +run: 0x00000001 opcode: 0f
 79 +run: jump 5
 80 +run: 0x0000000c opcode: 05
 81 -run: 0x00000007 opcode: 05
 82 
 83 :(before "End Two-Byte Opcodes Starting With 0f")
 84 case 0x85: {  // jump disp32 unless ZF
 85   const int32_t offset = next32();
 86   if (!ZF) {
 87     trace(Callstack_depth+1, "run") << "jump " << NUM(offset) << end();
 88     EIP += offset;
 89   }
 90   break;
 91 }
 92 
 93 :(scenario jne_disp32_fail)
 94 % ZF = true;
 95 == 0x1
 96 # op      ModR/M  SIB   displacement  immediate
 97   0f 85                 05 00 00 00               # skip 1 instruction
 98   05                                  00 00 00 01
 99   05                                  00 00 00 02
100 +run: 0x00000001 opcode: 0f
101 +run: 0x00000007 opcode: 05
102 +run: 0x0000000c opcode: 05
103 -run: jump 5
104 
105 //:: jump if greater
106 
107 :(before "End Initialize Op Names")
108 put_new(Name_0f, "8f", "jump disp32 bytes away if greater, if ZF is unset and SF == OF (jcc/jg/jnle)");
109 
110 :(scenario jg_disp32_success)
111 % ZF = false;
112 % SF = false;
113 % OF = false;
114 == 0x1
115 # op      ModR/M  SIB   displacement  immediate
116   0f 8f                 05 00 00 00               # skip 1 instruction
117   05                                  00 00 00 01
118   05                                  00 00 00 02
119 +run: 0x00000001 opcode: 0f
120 +run: jump 5
121 +run: 0x0000000c opcode: 05
122 -run: 0x00000007 opcode: 05
123 
124 :(before "End Two-Byte Opcodes Starting With 0f")
125 case 0x8f: {  // jump disp32 if !SF and !ZF
126   const int32_t offset = next32();
127   if (!ZF && SF == OF) {
128     trace(Callstack_depth+1, "run") << "jump " << NUM(offset) << end();
129     EIP += offset;
130   }
131   break;
132 }
133 
134 :(scenario jg_disp32_fail)
135 % ZF = false;
136 % SF = true;
137 % OF = false;
138 == 0x1
139 # op      ModR/M  SIB   displacement  immediate
140   0f 8f                 05 00 00 00               # skip 1 instruction
141   05                                  00 00 00 01
142   05                                  00 00 00 02
143 +run: 0x00000001 opcode: 0f
144 +run: 0x00000007 opcode: 05
145 +run: 0x0000000c opcode: 05
146 -run: jump 5
147 
148 //:: jump if greater or equal
149 
150 :(before "End Initialize Op Names")
151 put_new(Name_0f, "8d", "jump disp32 bytes away if greater or equal, if SF == OF (jcc/jge/jnl)");
152 
153 :(scenario jge_disp32_success)
154 % SF = false;
155 % OF = false;
156 == 0x1
157 # op      ModR/M  SIB   displacement  immediate
158   0f 8d                 05 00 00 00               # skip 1 instruction
159   05                                  00 00 00 01
160   05                                  00 00 00 02
161 +run: 0x00000001 opcode: 0f
162 +run: jump 5
163 +run: 0x0000000c opcode: 05
164 -run: 0x00000007 opcode: 05
165 
166 :(before "End Two-Byte Opcodes Starting With 0f")
167 case 0x8d: {  // jump disp32 if !SF
168   const int32_t offset = next32();
169   if (SF == OF) {
170     trace(Callstack_depth+1, "run") << "jump " << NUM(offset) << end();
171     EIP += offset;
172   }
173   break;
174 }
175 
176 :(scenario jge_disp32_fail)
177 % SF = true;
178 % OF = false;
179 == 0x1
180 # op      ModR/M  SIB   displacement  immediate
181   0f 8d                 05 00 00 00               # skip 1 instruction
182   05                                  00 00 00 01
183   05                                  00 00 00 02
184 +run: 0x00000001 opcode: 0f
185 +run: 0x00000007 opcode: 05
186 +run: 0x0000000c opcode: 05
187 -run: jump 5
188 
189 //:: jump if lesser
190 
191 :(before "End Initialize Op Names")
192 put_new(Name_0f, "8c", "jump disp32 bytes away if lesser, if SF != OF (jcc/jl/jnge)");
193 
194 :(scenario jl_disp32_success)
195 % ZF = false;
196 % SF = true;
197 % OF = false;
198 == 0x1
199 # op      ModR/M  SIB   displacement  immediate
200   0f 8c                 05 00 00 00               # skip 1 instruction
201   05                                  00 00 00 01
202   05                                  00 00 00 02
203 +run: 0x00000001 opcode: 0f
204 +run: jump 5
205 +run: 0x0000000c opcode: 05
206 -run: 0x00000007 opcode: 05
207 
208 :(before "End Two-Byte Opcodes Starting With 0f")
209 case 0x8c: {  // jump disp32 if SF and !ZF
210   const int32_t offset = next32();
211   if (SF != OF) {
212     trace(Callstack_depth+1, "run") << "jump " << NUM(offset) << end();
213     EIP += offset;
214   }
215   break;
216 }
217 
218 :(scenario jl_disp32_fail)
219 % ZF = false;
220 % SF = false;
221 % OF = false;
222 == 0x1
223 # op      ModR/M  SIB   displacement  immediate
224   0f 8c                 05 00 00 00               # skip 1 instruction
225   05                                  00 00 00 01
226   05                                  00 00 00 02
227 +run: 0x00000001 opcode: 0f
228 +run: 0x00000007 opcode: 05
229 +run: 0x0000000c opcode: 05
230 -run: jump 5
231 
232 //:: jump if lesser or equal
233 
234 :(before "End Initialize Op Names")
235 put_new(Name_0f, "8e", "jump disp32 bytes away if lesser or equal, if ZF is set or SF != OF (jcc/jle/jng)");
236 
237 :(scenario jle_disp32_equal)
238 % ZF = true;
239 % SF = false;
240 % OF = false;
241 == 0x1
242 # op      ModR/M  SIB   displacement  immediate
243   0f 8e                 05 00 00 00               # skip 1 instruction
244   05                                  00 00 00 01
245   05                                  00 00 00 02
246 +run: 0x00000001 opcode: 0f
247 +run: jump 5
248 +run: 0x0000000c opcode: 05
249 -run: 0x00000007 opcode: 05
250 
251 :(scenario jle_disp32_lesser)
252 % ZF = false;
253 % SF = true;
254 % OF = false;
255 == 0x1
256 # op      ModR/M  SIB   displacement  immediate
257   0f 8e                 05 00 00 00               # skip 1 instruction
258   05                                  00 00 00 01
259   05                                  00 00 00 02
260 +run: 0x00000001 opcode: 0f
261 +run: jump 5
262 +run: 0x0000000c opcode: 05
263 -run: 0x00000007 opcode: 05
264 
265 :(before "End Two-Byte Opcodes Starting With 0f")
266 case 0x8e: {  // jump disp32 if SF or ZF
267   const int32_t offset = next32();
268   if (ZF || SF != OF) {
269     trace(Callstack_depth+1, "run") << "jump " << NUM(offset) << end();
270     EIP += offset;
271   }
272   break;
273 }
274 
275 :(scenario jle_disp32_greater)
276 % ZF = false;
277 % SF = false;
278 % OF = false;
279 == 0x1
280 # op      ModR/M  SIB   displacement  immediate
281   0f 8e                 05 00 00 00               # skip 1 instruction
282   05                                  00 00 00 01
283   05                                  00 00 00 02
284 +run: 0x00000001 opcode: 0f
285 +run: 0x00000007 opcode: 05
286 +run: 0x0000000c opcode: 05
287 -run: jump 5