# Mu - subx/018jump_disp16.cc

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