16 #define ENCODING_SHIFT 0
17 #define OPTYPE_SHIFT 6
18 #define REGMASK_SHIFT 16
19 #define OPSIZE_SHIFT 24
22 #define OT_REGMEM (1 << (ENCODING_SHIFT + 0))
23 #define OT_SPECIAL (1 << (ENCODING_SHIFT + 1))
24 #define OT_IMMEDIATE (1 << (ENCODING_SHIFT + 2))
25 #define OT_JMPADDRESS (1 << (ENCODING_SHIFT + 3))
28 #define OT_REGALL (0xff << REGMASK_SHIFT)
31 #define OT_MEMORY (1 << (OPTYPE_SHIFT + 0))
32 #define OT_CONSTANT (1 << (OPTYPE_SHIFT + 1))
33 #define OT_GPREG ((1 << (OPTYPE_SHIFT + 2)) | OT_REGALL)
34 #define OT_SEGMENTREG ((1 << (OPTYPE_SHIFT + 3)) | OT_REGALL)
35 #define OT_FPUREG ((1 << (OPTYPE_SHIFT + 4)) | OT_REGALL)
36 #define OT_MMXREG ((1 << (OPTYPE_SHIFT + 5)) | OT_REGALL)
37 #define OT_XMMREG ((1 << (OPTYPE_SHIFT + 6)) | OT_REGALL)
38 #define OT_CONTROLREG ((1 << (OPTYPE_SHIFT + 7)) | OT_REGALL)
39 #define OT_DEBUGREG ((1 << (OPTYPE_SHIFT + 8)) | OT_REGALL)
40 #define OT_SREG ((1 << (OPTYPE_SHIFT + 9)) | OT_REGALL)
43 #define OT_REGTYPE ((OT_GPREG | OT_SEGMENTREG | OT_FPUREG | OT_MMXREG | OT_XMMREG | OT_CONTROLREG | OT_DEBUGREG) & ~OT_REGALL)
46 #define OT_REG(num) ((1 << (REGMASK_SHIFT + (num))) | OT_REGTYPE)
48 #define OT_UNKNOWN (0 << OPSIZE_SHIFT)
49 #define OT_BYTE (1 << OPSIZE_SHIFT)
50 #define OT_WORD (2 << OPSIZE_SHIFT)
51 #define OT_DWORD (4 << OPSIZE_SHIFT)
52 #define OT_QWORD (8 << OPSIZE_SHIFT)
53 #define OT_OWORD (16 << OPSIZE_SHIFT)
54 #define OT_TBYTE (32 << OPSIZE_SHIFT)
56 #define ALL_SIZE (OT_BYTE | OT_WORD | OT_DWORD | OT_QWORD | OT_OWORD)
60 #define OT_FPUSIZE (OT_DWORD | OT_QWORD | OT_TBYTE)
61 #define OT_XMMSIZE (OT_DWORD | OT_QWORD | OT_OWORD)
64 #define OT_REGMEMOP(type) (OT_##type##REG | OT_MEMORY | OT_REGMEM)
65 #define OT_REGONLYOP(type) (OT_##type##REG | OT_REGMEM)
66 #define OT_MEMONLYOP (OT_MEMORY | OT_REGMEM)
67 #define OT_MEMIMMOP (OT_MEMORY | OT_IMMEDIATE)
68 #define OT_REGSPECOP(type) (OT_##type##REG | OT_SPECIAL)
69 #define OT_IMMOP (OT_CONSTANT | OT_IMMEDIATE)
70 #define OT_MEMADDROP (OT_MEMORY | OT_IMMEDIATE)
73 #define SPECIAL_SPEC 0x00010000
74 #define SPECIAL_MASK 0x00000007
76 #define MAX_OPERANDS 3
77 #define MAX_REPOP_LENGTH 20
79 #define is_valid_registers(op) \
80 if (is_debug_or_control(op->operands[0]) || is_debug_or_control(op->operands[1])) \
206 return (sib & 0x8) ? 3 :
getsib((sib << 1) | 1) - 1;
224 int immediate =
op->operands[1].immediate *
op->operands[1].sign;
227 if (
op->operands[1].immediate < 128) {
229 data[l++] =
op->operands[0].reg | (0xc0 + op1 +
op->operands[0].reg);
232 data[l++] = 0x05 + op1;
235 data[l++] = (0xc0 + op1) |
op->operands[0].reg;
238 data[l++] = immediate;
239 if (
op->operands[1].immediate > 127) {
240 data[l++] = immediate >> 8;
255 if (!
op->operands[1].is_good_flag) {
258 if (
a->bits == 64 &&
op->operands[0].type &
OT_QWORD) {
261 if (!strcmp(
op->mnemonic,
"adc")) {
263 }
else if (!strcmp(
op->mnemonic,
"add")) {
265 }
else if (!strcmp(
op->mnemonic,
"or")) {
267 }
else if (!strcmp(
op->mnemonic,
"and")) {
269 }
else if (!strcmp(
op->mnemonic,
"xor")) {
271 }
else if (!strcmp(
op->mnemonic,
"sbb")) {
273 }
else if (!strcmp(
op->mnemonic,
"sub")) {
275 }
else if (!strcmp(
op->mnemonic,
"cmp")) {
278 immediate =
op->operands[1].immediate *
op->operands[1].sign;
282 if (
op->operands[1].immediate < 128) {
288 }
else if (
op->operands[0].type &
OT_BYTE) {
289 if (
op->operands[1].immediate > 255) {
290 RZ_LOG_ERROR(
"assembler: x86.nz: %s: the immediate value exceeds bounds (imm > 255)\n",
op->mnemonic);
296 offset =
op->operands[0].offset *
op->operands[0].offset_sign;
297 if (
op->operands[0].offset ||
op->operands[0].regs[0] ==
X86R_EBP) {
303 int reg0 =
op->operands[0].regs[0];
309 data[l++] = mod_byte << 6 | modrm << 3 | reg0;
313 if (mod_byte || mem_ref) {
315 if (mod_byte == 2 || mem_ref) {
322 if (
op->operands[1].immediate > 127 &&
op->operands[0].reg ==
X86R_EAX) {
323 data[l++] = 5 | modrm << 3 |
op->operands[0].reg;
326 data[l++] = mod_byte << 6 | modrm << 3 |
op->operands[0].reg;
330 data[l++] = immediate;
331 if ((immediate > 127 || immediate < -128) &&
333 data[l++] = immediate >> 8;
334 data[l++] = immediate >> 16;
335 data[l++] = immediate >> 24;
347 if (
a->bits == 64 &&
op->operands[0].type &
OT_QWORD) {
351 if (!strcmp(
op->mnemonic,
"rol")) {
353 }
else if (!strcmp(
op->mnemonic,
"ror")) {
355 }
else if (!strcmp(
op->mnemonic,
"rcl")) {
357 }
else if (!strcmp(
op->mnemonic,
"rcr")) {
359 }
else if (!strcmp(
op->mnemonic,
"shl")) {
361 }
else if (!strcmp(
op->mnemonic,
"shr")) {
363 }
else if (!strcmp(
op->mnemonic,
"sal")) {
365 }
else if (!strcmp(
op->mnemonic,
"sar")) {
369 st32 immediate =
op->operands[1].immediate *
op->operands[1].sign;
370 if (immediate > 255 || immediate < -128) {
371 RZ_LOG_ERROR(
"assembler: x86.nz: %s: the immediate value exceeds bounds (imm > 255 or imm < -128)\n",
op->mnemonic);
378 }
else if (immediate == 1) {
383 }
else if (
op->operands[0].type &
OT_BYTE) {
385 if (o->
regs[0] != -1 && o->
regs[1] != -1) {
388 data[l++] = o->
regs[0] | (o->
regs[1] << 3);
390 data[l++] = immediate;
394 }
else if (immediate == 1) {
401 reg0 =
op->operands[0].regs[0];
404 reg0 =
op->operands[0].reg;
407 data[l++] = mod_byte << 6 | modrm << 3 | reg0;
408 if (immediate != 1 && !(
op->operands[1].type &
OT_GPREG)) {
409 data[l++] = immediate;
425 if (!
op->operands[1].is_good_flag) {
431 data[l++] =
op->operands[1].immediate *
op->operands[1].sign;
436 if (!(
op->operands[0].type &
op->operands[1].type)) {
442 if (
op->operands[0].extended) {
445 if (
op->operands[1].extended) {
448 data[l++] = 0x48 | rex;
452 if (
a->bits == 64 && (
op->operands[0].type &
OT_DWORD) &&
460 data[l++] = op1 + 0x1;
462 RZ_LOG_ERROR(
"assembler: x86.nz: %s: mismatched operand sizes\n",
op->mnemonic);
465 reg =
op->operands[1].reg;
466 rm =
op->operands[0].regs[0];
467 offset =
op->operands[0].offset *
op->operands[0].offset_sign;
479 offset =
op->operands[0].regs[1] << 3;
485 data[l++] = op1 + 0x2;
488 data[l++] = op1 + 0x3;
490 RZ_LOG_ERROR(
"assembler: x86.nz: %s: mismatched operand sizes\n",
op->mnemonic);
493 reg =
op->operands[0].reg;
494 rm =
op->operands[1].regs[0];
496 if (
op->operands[1].scale[0] > 1) {
498 data[l++] =
op->operands[0].reg << 3 | 4;
499 data[l++] =
getsib(
op->operands[1].scale[0]) << 6 |
500 op->operands[1].regs[0] << 3 |
501 op->operands[1].regs[1];
504 data[l++] =
op->operands[0].reg << 3 | 4;
505 data[l++] =
getsib(
op->operands[1].scale[0]) << 6 |
op->operands[1].regs[0] << 3 | 5;
506 data[l++] =
op->operands[1].offset *
op->operands[1].offset_sign;
512 offset =
op->operands[1].offset *
op->operands[1].offset_sign;
524 data[l++] = op1 + 0x1;
529 data[l++] = op1 + 0x1;
534 reg =
op->operands[1].reg;
535 rm =
op->operands[0].reg;
543 data[l++] = mod_byte << 6 |
reg << 3 | rm;
549 if (
offset || mem_ref || ebp_reg) {
552 if (mod_byte == 2 || mem_ref) {
642 if (
op->operands_count < 2) {
658 data[
i] |= (
op->operands[1].reg << 3);
659 data[
i++] |=
op->operands[0].reg;
666 if (
op->operands_count < 2) {
703 data[l++] = 0xd8 |
op->operands[0].reg;
710 memcpy(data,
"\xf3\x0f\x1e\xfa", 4);
715 memcpy(data,
"\xf3\x0f\x1e\xfb", 4);
728 if (
op->operands[0].explicit_size) {
729 size =
op->operands[0].dest_size;
733 bool use_rex =
false;
738 if (
op->operands[0].extended) {
747 data[l++] = 0xd0 |
op->operands[0].reg;
786 }
else if (
op->operands[0].type &
OT_WORD) {
790 if (!strcmp(
op->mnemonic,
"bsf")) {
800 data[l] +=
op->operands[0].reg << 3;
801 data[l++] +=
op->operands[1].reg;
815 if (
op->operands[0].extended) {
821 data[l++] = 0xc8 +
op->operands[0].reg;
823 if (
op->operands[0].extended) {
827 data[l++] = 0xc8 +
op->operands[0].reg;
846 if (
a->bits == 64 &&
op->operands[0].extended) {
851 data[l++] =
mod << 6 | 2 << 3 |
op->operands[0].reg;
857 offset =
op->operands[0].offset *
op->operands[0].offset_sign;
864 data[l++] =
mod << 6 | 2 << 3 |
op->operands[0].regs[0];
874 ut64 instr_offset =
a->pc;
876 immediate =
op->operands[0].immediate *
op->operands[0].sign;
877 immediate -= instr_offset + 5;
878 data[l++] = immediate;
879 data[l++] = immediate >> 8;
880 data[l++] = immediate >> 16;
881 data[l++] = immediate >> 24;
898 char *cmov =
op->mnemonic + 4;
899 if (!strcmp(cmov,
"o")) {
901 }
else if (!strcmp(cmov,
"no")) {
903 }
else if (!strcmp(cmov,
"b") ||
904 !strcmp(cmov,
"c") ||
905 !strcmp(cmov,
"nae")) {
907 }
else if (!strcmp(cmov,
"ae") ||
908 !strcmp(cmov,
"nb") ||
909 !strcmp(cmov,
"nc")) {
911 }
else if (!strcmp(cmov,
"e") ||
912 !strcmp(cmov,
"z")) {
914 }
else if (!strcmp(cmov,
"ne") ||
915 !strcmp(cmov,
"nz")) {
917 }
else if (!strcmp(cmov,
"be") ||
918 !strcmp(cmov,
"na")) {
920 }
else if (!strcmp(cmov,
"a") ||
921 !strcmp(cmov,
"nbe")) {
923 }
else if (!strcmp(cmov,
"s")) {
925 }
else if (!strcmp(cmov,
"ns")) {
927 }
else if (!strcmp(cmov,
"p") ||
928 !strcmp(cmov,
"pe")) {
930 }
else if (!strcmp(cmov,
"np") ||
931 !strcmp(cmov,
"po")) {
933 }
else if (!strcmp(cmov,
"l") ||
934 !strcmp(cmov,
"nge")) {
936 }
else if (!strcmp(cmov,
"ge") ||
937 !strcmp(cmov,
"nl")) {
939 }
else if (!strcmp(cmov,
"le") ||
940 !strcmp(cmov,
"ng")) {
942 }
else if (!strcmp(cmov,
"g") ||
943 !strcmp(cmov,
"nle")) {
949 if (
op->operands[1].scale[0] > 1) {
951 data[l++] =
op->operands[0].reg << 3 | 4;
952 data[l++] =
getsib(
op->operands[1].scale[0]) << 6 |
953 op->operands[1].regs[0] << 3 |
954 op->operands[1].regs[1];
957 offset =
op->operands[1].offset *
op->operands[1].offset_sign;
959 if (
op->operands[1].scale[0] == 2 &&
offset) {
960 data[l++] = 0x40 |
op->operands[0].reg << 3 | 4;
962 data[l++] =
op->operands[0].reg << 3 | 4;
965 if (
op->operands[1].scale[0] == 2) {
966 data[l++] =
op->operands[1].regs[0] << 3 |
op->operands[1].regs[0];
969 data[l++] =
getsib(
op->operands[1].scale[0]) << 6 |
970 op->operands[1].regs[0] << 3 | 5;
984 data[l++] =
op->operands[0].reg << 3 | 4;
985 data[l++] =
op->operands[1].regs[1] << 3 |
op->operands[1].regs[0];
989 offset =
op->operands[1].offset *
op->operands[1].offset_sign;
990 if (
op->operands[1].offset ||
op->operands[1].regs[0] ==
X86R_EBP) {
997 data[l++] = mod_byte << 6 |
op->operands[0].reg << 3 |
op->operands[1].regs[0];
1001 if (mod_byte == 2) {
1003 data[l++] =
offset >> 16;
1004 data[l++] =
offset >> 24;
1008 data[l++] = 0xc0 |
op->operands[0].reg << 3 |
op->operands[1].reg;
1019 char *movx =
op->mnemonic + 3;
1029 if (!strcmp(movx,
"zx")) {
1030 data[l++] = 0xb6 + word;
1031 }
else if (!strcmp(movx,
"sx")) {
1032 data[l++] = 0xbe + word;
1034 data[l++] =
op->operands[0].reg << 3 |
op->operands[1].regs[0];
1045 int immediate =
op->operands[0].immediate *
op->operands[0].sign;
1047 if (immediate == 0) {
1049 }
else if (immediate < 256 && immediate > -129) {
1050 data[l++] = immediate;
1056 if (
op->operands[1].type) {
1057 RZ_LOG_ERROR(
"assembler: x86.nz: %s: invalid operands\n",
op->mnemonic);
1063 if (
op->operands[0].explicit_size) {
1064 size =
op->operands[0].dest_size;
1073 bool use_rex =
false;
1078 if (
op->operands[0].extended) {
1099 data[l++] = 0x48 |
op->operands[0].reg;
1101 data[l++] = 0xc8 |
op->operands[0].reg;
1107 bool rip_rel =
op->operands[0].regs[0] ==
X86R_RIP;
1108 int offset =
op->operands[0].offset *
op->operands[0].offset_sign;
1113 bool use_sib =
false;
1124 if (
op->operands[0].regs[0] &
OT_WORD) {
1127 }
else if (
op->operands[0].regs[0] ==
X86R_BX &&
op->operands[0].regs[1] ==
X86R_DI) {
1129 }
else if (
op->operands[0].regs[0] ==
X86R_BP &&
op->operands[0].regs[1] ==
X86R_SI) {
1131 }
else if (
op->operands[0].regs[0] ==
X86R_BP &&
op->operands[0].regs[1] ==
X86R_DI) {
1133 }
else if (
op->operands[0].regs[0] ==
X86R_SI &&
op->operands[0].regs[1] == -1) {
1135 }
else if (
op->operands[0].regs[0] ==
X86R_DI &&
op->operands[0].regs[1] == -1) {
1137 }
else if (
op->operands[0].regs[0] ==
X86R_BX &&
op->operands[0].regs[1] == -1) {
1143 modrm = (
mod << 6) | (
reg << 3) | rm;
1146 if (
op->operands[0].extended) {
1147 rm =
op->operands[0].reg;
1149 rm =
op->operands[0].regs[0];
1152 if (rm == 5 &&
mod == 0) {
1157 int index =
op->operands[0].regs[1];
1158 int scale =
getsib(
op->operands[0].scale[1]);
1161 sib = (scale << 6) | (index << 3) | rm;
1162 }
else if (rm == 4) {
1173 modrm = (
mod << 6) | (
reg << 3) | rm;
1189 }
else if (
op->operands[0].regs[0] &
OT_WORD &&
mod == 2) {
1192 }
else if (
mod == 2 || rip_rel) {
1195 data[l++] =
offset >> 16;
1196 data[l++] =
offset >> 24;
1209 switch (
op->operands_count) {
1220 data[l++] = 0x38 |
op->operands[0].regs[0];
1222 data[l++] = 0xf8 |
op->operands[0].reg;
1238 switch (
op->operands_count) {
1249 data[l++] = 0x30 |
op->operands[0].regs[0];
1251 data[l++] = 0xf0 |
op->operands[0].reg;
1269 switch (
op->operands_count) {
1280 data[l++] = 0x28 |
op->operands[0].regs[0];
1282 data[l++] = 0xe8 |
op->operands[0].reg;
1288 if (
op->operands[1].immediate == -1) {
1289 RZ_LOG_ERROR(
"assembler: x86.nz: %s: immediate operand exceeds max value (imm == -1)\n",
op->mnemonic);
1292 immediate =
op->operands[1].immediate *
op->operands[1].sign;
1294 if (immediate >= 128) {
1299 data[l++] = 0xc0 |
op->operands[0].reg << 3 |
op->operands[0].reg;
1300 data[l++] = immediate;
1301 if (immediate >= 128) {
1302 data[l++] = immediate >> 8;
1303 data[l++] = immediate >> 16;
1304 data[l++] = immediate >> 24;
1306 if (
a->bits == 64 && immediate >
UT32_MAX) {
1307 data[l++] = immediate >> 32;
1308 data[l++] = immediate >> 40;
1309 data[l++] = immediate >> 48;
1310 data[l++] = immediate >> 56;
1317 offset =
op->operands[1].offset *
op->operands[1].offset_sign;
1324 data[l++] |=
op->operands[0].reg << 3 |
op->operands[1].regs[0];
1328 data[l++] =
offset >> 16;
1329 data[l++] =
offset >> 24;
1333 data[l++] = 0x04 |
op->operands[0].reg << 3;
1334 data[l++] =
op->operands[1].regs[1] << 3 |
op->operands[1].regs[0];
1336 data[l++] =
op->operands[0].reg << 3 |
op->operands[1].regs[0];
1340 immediate =
op->operands[1].immediate *
op->operands[1].sign;
1341 data[l++] =
op->operands[0].reg << 3 | 0x5;
1342 data[l++] = immediate;
1343 data[l++] = immediate >> 8;
1344 data[l++] = immediate >> 16;
1345 data[l++] = immediate >> 24;
1347 }
else if (
op->operands[1].type &
OT_GPREG) {
1350 data[l++] = 0xc0 |
op->operands[0].reg << 3 |
op->operands[1].reg;
1361 data[l++] = 0x04 |
op->operands[0].reg << 3;
1362 data[l++] =
op->operands[1].regs[0] |
op->operands[1].regs[1] << 3;
1364 offset =
op->operands[1].offset *
op->operands[1].offset_sign;
1371 data[l++] |=
op->operands[0].reg << 3;
1375 data[l++] =
offset >> 16;
1376 data[l++] =
offset >> 24;
1379 data[l++] = 0x00 |
op->operands[0].reg << 3 |
op->operands[1].regs[0];
1383 data[l++] = 0xc0 |
op->operands[0].reg << 3 |
op->operands[1].reg;
1385 immediate =
op->operands[2].immediate *
op->operands[2].sign;
1386 data[l++] = immediate;
1387 if (immediate >= 128 || immediate <= -128) {
1388 data[l++] = immediate >> 8;
1389 data[l++] = immediate >> 16;
1390 data[l++] = immediate >> 24;
1422 immediate =
op->operands[1].immediate *
op->operands[1].sign;
1423 if (immediate > 255 || immediate < -128) {
1429 }
else if (
op->operands[0].reg ==
X86R_AX &&
1433 }
else if (
op->operands[0].reg ==
X86R_EAX &&
1437 data[l++] = immediate;
1451 offset =
op->operands[0].offset *
op->operands[0].offset_sign;
1459 data[l++] = (mod_byte << 6) | (7 << 3) |
op->operands[0].regs[0];
1462 if (mod_byte == 2) {
1464 data[l++] =
offset >> 16;
1465 data[l++] =
offset >> 24;
1473 if (
op->operands[1].type) {
1474 RZ_LOG_ERROR(
"assembler: x86.nz: %s: invalid operands\n",
op->mnemonic);
1480 if (
op->operands[0].explicit_size) {
1481 size =
op->operands[0].dest_size;
1490 bool use_rex =
false;
1495 if (
op->operands[0].extended) {
1516 data[l++] = 0x40 |
op->operands[0].reg;
1518 data[l++] = 0xc0 |
op->operands[0].reg;
1524 bool rip_rel =
op->operands[0].regs[0] ==
X86R_RIP;
1525 int offset =
op->operands[0].offset *
op->operands[0].offset_sign;
1530 bool use_sib =
false;
1541 if (
op->operands[0].regs[0] &
OT_WORD) {
1544 }
else if (
op->operands[0].regs[0] ==
X86R_BX &&
op->operands[0].regs[1] ==
X86R_DI) {
1546 }
else if (
op->operands[0].regs[0] ==
X86R_BP &&
op->operands[0].regs[1] ==
X86R_SI) {
1548 }
else if (
op->operands[0].regs[0] ==
X86R_BP &&
op->operands[0].regs[1] ==
X86R_DI) {
1550 }
else if (
op->operands[0].regs[0] ==
X86R_SI &&
op->operands[0].regs[1] == -1) {
1552 }
else if (
op->operands[0].regs[0] ==
X86R_DI &&
op->operands[0].regs[1] == -1) {
1554 }
else if (
op->operands[0].regs[0] ==
X86R_BX &&
op->operands[0].regs[1] == -1) {
1560 modrm = (
mod << 6) | (
reg << 3) | rm;
1563 if (
op->operands[0].extended) {
1564 rm =
op->operands[0].reg;
1566 rm =
op->operands[0].regs[0];
1569 if (rm == 5 &&
mod == 0) {
1574 int index =
op->operands[0].regs[1];
1575 int scale =
getsib(
op->operands[0].scale[1]);
1578 sib = (scale << 6) | (index << 3) | rm;
1579 }
else if (rm == 4) {
1590 modrm = (
mod << 6) | (
reg << 3) | rm;
1605 }
else if (
op->operands[0].regs[0] &
OT_WORD &&
mod == 2) {
1608 }
else if (
mod == 2 || rip_rel) {
1611 data[l++] =
offset >> 16;
1612 data[l++] =
offset >> 24;
1621 st32 immediate =
op->operands[0].immediate *
op->operands[0].sign;
1622 if (immediate <= 255 && immediate >= -128) {
1624 data[l++] = immediate;
1633 bool is_short =
op->is_short;
1635 st64 immediate =
op->operands[0].immediate *
op->operands[0].sign;
1643 if (!strcmp(
op->mnemonic,
"jmp")) {
1647 if (
op->operands[0].offset) {
1648 int offset =
op->operands[0].offset *
op->operands[0].offset_sign;
1654 data[l++] |=
op->operands[0].regs[0];
1659 if (
op->operands[0].offset >= 0x80) {
1661 data[l++] =
offset >> 16;
1662 data[l++] =
offset >> 24;
1665 data[l++] = 0x20 |
op->operands[0].regs[0];
1668 data[l++] = 0xe0 |
op->operands[0].reg;
1671 if (-0x80 <= (immediate - 2) && (immediate - 2) <= 0x7f) {
1674 data[l++] = immediate - 2;
1679 data[l++] = immediate;
1680 data[l++] = immediate >> 8;
1681 data[l++] = immediate >> 16;
1682 data[l++] = immediate >> 24;
1687 if (immediate <= 0x81 && immediate > -0x7f) {
1690 if (
a->bits == 16 && (immediate > 0x81 || immediate < -0x7e)) {
1699 if (!strcmp(
op->mnemonic,
"ja") ||
1700 !strcmp(
op->mnemonic,
"jnbe")) {
1702 }
else if (!strcmp(
op->mnemonic,
"jae") ||
1703 !strcmp(
op->mnemonic,
"jnb") ||
1704 !strcmp(
op->mnemonic,
"jnc")) {
1706 }
else if (!strcmp(
op->mnemonic,
"jz") ||
1707 !strcmp(
op->mnemonic,
"je")) {
1709 }
else if (!strcmp(
op->mnemonic,
"jb") ||
1710 !strcmp(
op->mnemonic,
"jnae") ||
1711 !strcmp(
op->mnemonic,
"jc")) {
1713 }
else if (!strcmp(
op->mnemonic,
"jbe") ||
1714 !strcmp(
op->mnemonic,
"jna")) {
1716 }
else if (!strcmp(
op->mnemonic,
"jg") ||
1717 !strcmp(
op->mnemonic,
"jnle")) {
1719 }
else if (!strcmp(
op->mnemonic,
"jge") ||
1720 !strcmp(
op->mnemonic,
"jnl")) {
1722 }
else if (!strcmp(
op->mnemonic,
"jl") ||
1723 !strcmp(
op->mnemonic,
"jnge")) {
1725 }
else if (!strcmp(
op->mnemonic,
"jle") ||
1726 !strcmp(
op->mnemonic,
"jng")) {
1728 }
else if (!strcmp(
op->mnemonic,
"jne") ||
1729 !strcmp(
op->mnemonic,
"jnz")) {
1731 }
else if (!strcmp(
op->mnemonic,
"jno")) {
1733 }
else if (!strcmp(
op->mnemonic,
"jnp") ||
1734 !strcmp(
op->mnemonic,
"jpo")) {
1736 }
else if (!strcmp(
op->mnemonic,
"jns")) {
1738 }
else if (!strcmp(
op->mnemonic,
"jo")) {
1740 }
else if (!strcmp(
op->mnemonic,
"jp") ||
1741 !strcmp(
op->mnemonic,
"jpe")) {
1743 }
else if (!strcmp(
op->mnemonic,
"js") ||
1744 !strcmp(
op->mnemonic,
"jz")) {
1748 data[l - 1] -= 0x10;
1751 immediate -= is_short ? 2 : 6;
1752 data[l++] = immediate;
1754 data[l++] = immediate >> 8;
1755 data[l++] = immediate >> 16;
1756 data[l++] = immediate >> 24;
1769 if (
a->bits == 64) {
1776 if (data[0] == 0x48) {
1780 data[l++] =
op->operands[0].reg << 3 | 5;
1782 data[l++] = high >> 8;
1783 data[l++] =
offset >> 16;
1784 data[l++] =
offset >> 24;
1787 reg =
op->operands[0].reg;
1788 rm =
op->operands[1].regs[0];
1790 offset =
op->operands[1].offset *
op->operands[1].offset_sign;
1793 data[l++] =
reg << 3 | 5;
1796 data[l++] =
offset >> 16;
1797 data[l++] =
offset >> 24;
1805 data[l++] =
mod << 6 |
reg << 3 | rm;
1812 data[l++] =
offset >> 16;
1813 data[l++] =
offset >> 24;
1816 data[l++] =
op->operands[0].reg << 3 |
op->operands[1].regs[0];
1834 offset =
op->operands[1].offset *
op->operands[1].offset_sign;
1841 data[l++] =
mod << 6 |
op->operands[0].reg << 3 |
op->operands[1].regs[0];
1846 data[l++] =
offset >> 16;
1847 data[l++] =
offset >> 24;
1851 offset =
op->operands[1].offset *
op->operands[1].offset_sign;
1855 data[l++] =
offset >> 16;
1856 data[l++] =
offset >> 24;
1870 if (!
op->operands[1].is_good_flag) {
1873 if (
op->operands[1].immediate == -1 &&
a->num &&
a->num->nc.errors > 0) {
1876 immediate =
op->operands[1].immediate *
op->operands[1].sign;
1879 immediate >
UT32_MAX && immediate < 0xffffffff80000000ULL ) {
1882 bool imm32in64 =
false;
1883 if (
a->bits == 64 && (
op->operands[0].type &
OT_QWORD)) {
1884 if (
op->operands[0].extended) {
1889 }
else if (
op->operands[0].extended) {
1898 data[l++] = 0xb0 |
op->operands[0].reg;
1899 data[l++] = immediate;
1901 if (
a->bits == 64 && (
op->operands[0].type &
OT_QWORD) &&
1902 (immediate <= ST32_MAX || immediate >= 0xffffffff80000000ULL )) {
1904 data[l++] = 0xc0 |
op->operands[0].reg;
1907 data[l++] = 0xb8 |
op->operands[0].reg;
1909 data[l++] = immediate;
1910 data[l++] = immediate >> 8;
1911 if (!(
op->operands[0].type &
OT_WORD)) {
1912 data[l++] = immediate >> 16;
1913 data[l++] = immediate >> 24;
1915 if (
a->bits == 64 &&
1916 (((
op->operands[0].type &
OT_QWORD) && !imm32in64) ||
1917 (immediate >
UT32_MAX && immediate < 0xffffffff80000000ULL ))) {
1918 data[l++] = immediate >> 32;
1919 data[l++] = immediate >> 40;
1920 data[l++] = immediate >> 48;
1921 data[l++] = immediate >> 56;
1925 if (!
op->operands[0].explicit_size) {
1927 ((
Opcode *)
op)->operands[0].dest_size =
op->operands[0].reg_size;
1935 int offset =
op->operands[0].offset *
op->operands[0].offset_sign;
1938 bool use_aso =
false;
1939 if (reg_bits < a->
bits) {
1944 bool use_oso =
false;
1945 if (dest_bits == 16) {
1949 bool rip_rel =
op->operands[0].regs[0] ==
X86R_RIP;
1953 bool use_rex =
false;
1954 if (dest_bits == 64) {
1958 if (
op->operands[0].extended) {
1965 if (dest_bits == 8) {
1976 bool use_sib =
false;
1990 }
else if (
op->operands[0].regs[0] ==
X86R_BX &&
op->operands[0].regs[1] ==
X86R_DI) {
1992 }
else if (
op->operands[0].regs[0] ==
X86R_BP &&
op->operands[0].regs[1] ==
X86R_SI) {
1994 }
else if (
op->operands[0].regs[0] ==
X86R_BP &&
op->operands[0].regs[1] ==
X86R_DI) {
1996 }
else if (
op->operands[0].regs[0] ==
X86R_SI &&
op->operands[0].regs[1] == -1) {
1998 }
else if (
op->operands[0].regs[0] ==
X86R_DI &&
op->operands[0].regs[1] == -1) {
2000 }
else if (
op->operands[0].regs[0] ==
X86R_BX &&
op->operands[0].regs[1] == -1) {
2006 modrm = (
mod << 6) | (
reg << 3) | rm;
2009 if (
op->operands[0].extended) {
2010 rm =
op->operands[0].reg;
2012 rm =
op->operands[0].regs[0];
2015 if (rm == 5 &&
mod == 0) {
2020 int index =
op->operands[0].regs[1];
2021 int scale =
getsib(
op->operands[0].scale[1]);
2024 sib = (scale << 6) | (index << 3) | rm;
2025 }
else if (rm == 4) {
2036 modrm = (
mod << 6) | (
reg << 3) | rm;
2061 }
else if (
mod == 2 || rip_rel) {
2064 data[l++] =
offset >> 16;
2065 data[l++] =
offset >> 24;
2069 for (
byte = 0;
byte < dest_bits &&
byte < 32;
byte += 8) {
2070 data[l++] = (immediate >> byte);
2098 if (
a->bits == 64) {
2099 if (
op->operands[0].extended) {
2102 if (
op->operands[1].extended) {
2113 data[l++] = 0x48 | rex;
2117 data[l++] = 0x40 | rex;
2119 }
else if (
op->operands[0].extended &&
op->operands[1].extended) {
2122 offset =
op->operands[0].offset *
op->operands[0].offset_sign;
2143 data[l++] = (
op->operands[0].type &
OT_BYTE) ? 0x88 : 0x89;
2146 if (
op->operands[0].scale[0] > 1) {
2147 data[l++] =
op->operands[1].reg << 3 | 4;
2148 data[l++] =
getsib(
op->operands[0].scale[0]) << 6 |
2149 op->operands[0].regs[0] << 3 | 5;
2153 data[l++] =
offset >> 16;
2154 data[l++] =
offset >> 24;
2166 ?
mod << 6 |
op->operands[0].reg << 3 |
op->operands[1].reg
2167 :
mod << 6 |
op->operands[1].reg << 3 |
op->operands[0].reg;
2169 data[l++] =
op->operands[1].reg << 3 | 0x5;
2172 data[l++] =
offset >> 16;
2173 data[l++] =
offset >> 24;
2177 data[l++] =
op->operands[1].reg << 3 | 0x4;
2178 data[l++] =
op->operands[0].regs[1] << 3 |
op->operands[0].regs[0];
2187 data[l++] =
mod << 6 |
op->operands[1].reg << 3 |
op->operands[0].regs[0];
2197 data[l++] =
offset >> 16;
2198 data[l++] =
offset >> 24;
2206 offset =
op->operands[1].offset *
op->operands[1].offset_sign;
2210 }
else if (
op->operands[0].type &
OT_WORD &&
a->bits != 16) {
2220 if (
a->bits >= 32) {
2221 data[l++] =
offset >> 16;
2222 data[l++] =
offset >> 24;
2223 if (
a->bits == 64) {
2224 data[l++] =
offset >> 32;
2225 data[l++] =
offset >> 40;
2226 data[l++] =
offset >> 48;
2227 data[l++] =
offset >> 56;
2232 if (
op->operands[0].type &
OT_BYTE &&
a->bits == 64 &&
op->operands[1].regs[0]) {
2233 if (
op->operands[1].regs[0] >=
X86R_R8 &&
2234 op->operands[0].reg < 4) {
2237 data[l++] =
op->operands[0].reg << 3 | (
op->operands[1].regs[0] - 8);
2244 if (
op->operands[1].scale[0] == 0) {
2249 data[l++] = (((
ut32)
op->operands[0].reg) << 3) | 0x5;
2252 data[l++] =
offset >> 16;
2253 data[l++] =
offset >> 24;
2257 if (
a->bits == 64) {
2260 if (
op->operands[1].regs[0] != -1) {
2265 }
else if (
op->operands[1].type &
OT_DWORD) {
2267 }
else if (!(
op->operands[1].type &
OT_QWORD)) {
2278 data[l++] =
op->operands[1].type &
OT_BYTE ? 0x8a : 0x8b;
2280 data[l++] = (
op->operands[1].type &
OT_BYTE ||
2287 if (
a->bits == 64) {
2288 data[l++] =
op->operands[0].reg << 3 | 0x4;
2291 data[l++] =
op->operands[0].reg << 3 | 0x5;
2295 data[l++] =
offset >> 16;
2296 data[l++] =
offset >> 24;
2298 if (
op->operands[1].scale[0] > 1) {
2299 data[l++] =
op->operands[0].reg << 3 | 4;
2301 if (
op->operands[1].scale[0] >= 2) {
2305 data[l++] =
getsib(
op->operands[1].scale[0]) << 6 |
op->operands[1].regs[0] << 3 | base;
2307 data[l++] =
getsib(
op->operands[1].scale[0]) << 3 |
op->operands[1].regs[0];
2312 data[l++] =
offset >> 16;
2313 data[l++] =
offset >> 24;
2318 data[l++] =
op->operands[0].reg << 3 | 0x4;
2319 data[l++] =
op->operands[1].regs[1] << 3 |
op->operands[1].regs[0];
2325 if (
op->operands[1].offset > 127) {
2333 const ut8 pfx = (
op->operands[1].offset > 127) ? 0x80 : 0x40;
2334 data[l++] = pfx |
op->operands[0].reg << 3 |
op->operands[1].regs[0];
2336 if (
op->operands[1].offset > 127) {
2345 data[l++] =
mod << 5 |
op->operands[0].reg << 3 |
op->operands[1].regs[0];
2353 if (
op->operands[1].offset > 128 ||
op->operands[1].regs[0] ==
X86R_EIP) {
2355 data[l++] =
offset >> 16;
2356 data[l++] =
offset >> 24;
2360 if (
op->operands[1].offset > 127 ||
op->operands[1].regs[0] ==
X86R_RIP) {
2362 data[l++] =
offset >> 16;
2363 data[l++] =
offset >> 24;
2380 if (
op->operands[0].extended) {
2385 data[l++] = 0xb8 |
op->operands[0].reg;
2386 immediate =
op->operands[1].immediate *
op->operands[1].sign;
2387 for (byte_shift = 0; byte_shift < 8; byte_shift++) {
2388 data[l++] = immediate >> (byte_shift * 8);
2400 switch (
op->operands_count) {
2411 data[l++] = 0x20 |
op->operands[0].regs[0];
2413 data[l++] = 0xe0 |
op->operands[0].reg;
2439 data[l++] = base + (8 *
op->operands[0].reg);
2441 if (
op->operands[0].extended &&
a->bits == 64) {
2445 data[l++] = base +
op->operands[0].reg;
2449 offset =
op->operands[0].offset *
op->operands[0].offset_sign;
2455 data[l++] =
mod << 6 |
op->operands[0].regs[0];
2462 data[l++] =
offset >> 16;
2463 data[l++] =
offset >> 24;
2466 data[l++] =
op->operands[0].regs[0];
2492 data[l++] = base + (8 *
op->operands[0].reg);
2494 if (
op->operands[0].extended &&
a->bits == 64) {
2499 RZ_LOG_ERROR(
"assembler: x86.nz: %s: invalid register (rip)\n",
op->mnemonic);
2502 data[l++] = base +
op->operands[0].reg;
2506 offset =
op->operands[0].offset *
op->operands[0].offset_sign;
2512 data[l++] =
mod << 6 | 6 << 3 |
op->operands[0].regs[0];
2519 data[l++] =
offset >> 16;
2520 data[l++] =
offset >> 24;
2524 data[l++] =
mod << 4 |
op->operands[0].regs[0];
2530 immediate =
op->operands[0].immediate *
op->operands[0].sign;
2531 if (immediate >= 128 || immediate < -128) {
2533 data[l++] = immediate;
2534 data[l++] = immediate >> 8;
2535 data[l++] = immediate >> 16;
2536 data[l++] = immediate >> 24;
2539 data[l++] = immediate;
2564 immediate =
op->operands[0].immediate *
op->operands[0].sign;
2565 if (immediate > 255 || immediate < -128) {
2578 data[l++] = immediate;
2589 st8 delta =
op->operands[0].immediate -
a->pc - 2;
2597 if (
a->bits == 16) {
2605 immediate =
op->operands[0].immediate *
op->operands[0].sign;
2606 data[l++] = immediate;
2607 data[l++] = immediate << 8;
2616 immediate =
op->operands[0].immediate *
op->operands[0].sign;
2618 data[l++] = immediate;
2619 data[l++] = immediate >> 8;
2629 if (!strcmp(
op->mnemonic,
"stosw")) {
2632 if (!strcmp(
op->mnemonic,
"stosb")) {
2634 }
else if (!strcmp(
op->mnemonic,
"stosw")) {
2636 }
else if (!strcmp(
op->mnemonic,
"stosd")) {
2648 int reg =
op->operands[0].regs[0];
2651 if (!strcmp(
op->mnemonic,
"seto")) {
2653 }
else if (!strcmp(
op->mnemonic,
"setno")) {
2655 }
else if (!strcmp(
op->mnemonic,
"setb") ||
2656 !strcmp(
op->mnemonic,
"setnae") ||
2657 !strcmp(
op->mnemonic,
"setc")) {
2659 }
else if (!strcmp(
op->mnemonic,
"setnb") ||
2660 !strcmp(
op->mnemonic,
"setae") ||
2661 !strcmp(
op->mnemonic,
"setnc")) {
2663 }
else if (!strcmp(
op->mnemonic,
"setz") ||
2664 !strcmp(
op->mnemonic,
"sete")) {
2666 }
else if (!strcmp(
op->mnemonic,
"setnz") ||
2667 !strcmp(
op->mnemonic,
"setne")) {
2669 }
else if (!strcmp(
op->mnemonic,
"setbe") ||
2670 !strcmp(
op->mnemonic,
"setna")) {
2672 }
else if (!strcmp(
op->mnemonic,
"setnbe") ||
2673 !strcmp(
op->mnemonic,
"seta")) {
2675 }
else if (!strcmp(
op->mnemonic,
"sets")) {
2677 }
else if (!strcmp(
op->mnemonic,
"setns")) {
2679 }
else if (!strcmp(
op->mnemonic,
"setp") ||
2680 !strcmp(
op->mnemonic,
"setpe")) {
2682 }
else if (!strcmp(
op->mnemonic,
"setnp") ||
2683 !strcmp(
op->mnemonic,
"setpo")) {
2685 }
else if (!strcmp(
op->mnemonic,
"setl") ||
2686 !strcmp(
op->mnemonic,
"setnge")) {
2688 }
else if (!strcmp(
op->mnemonic,
"setnl") ||
2689 !strcmp(
op->mnemonic,
"setge")) {
2691 }
else if (!strcmp(
op->mnemonic,
"setle") ||
2692 !strcmp(
op->mnemonic,
"setng")) {
2694 }
else if (!strcmp(
op->mnemonic,
"setnle") ||
2695 !strcmp(
op->mnemonic,
"setg")) {
2702 reg =
op->operands[0].reg;
2704 data[l++] =
mod << 6 |
reg;
2711 if (!
op->operands[0].type || !
op->operands[1].type) {
2712 RZ_LOG_ERROR(
"assembler: x86.nz: %s: invalid operands\n",
op->mnemonic);
2715 if (
a->bits == 64) {
2721 if (
op->operands[0].extended &&
2722 op->operands[1].extended) {
2734 if (
op->operands[0].type &
OT_WORD &&
a->bits != 16) {
2740 data[l++] = 0x00 |
op->operands[0].reg;
2742 data[l++] = 0xc0 |
op->operands[0].reg;
2744 data[l++] =
op->operands[1].immediate >> 0;
2748 data[l++] =
op->operands[1].immediate >> 8;
2752 data[l++] =
op->operands[1].immediate >> 16;
2753 data[l++] =
op->operands[1].immediate >> 24;
2763 data[l++] = 0x00 |
op->operands[1].reg << 3 |
op->operands[0].regs[0];
2766 data[l++] = 0x00 |
op->operands[0].reg << 3 |
op->operands[1].regs[0];
2768 data[l++] = 0xc0 |
op->operands[1].reg << 3 |
op->operands[0].reg;
2785 rm =
op->operands[0].regs[0];
2786 offset =
op->operands[0].offset *
op->operands[0].offset_sign;
2787 reg =
op->operands[1].reg;
2789 rm =
op->operands[1].regs[0];
2790 offset =
op->operands[1].offset *
op->operands[1].offset_sign;
2791 reg =
op->operands[0].reg;
2805 !
op->operands[0].extended &&
2810 }
else if (
op->operands[0].type &
OT_DWORD &&
2811 op->operands[1].extended) {
2813 }
else if (
op->operands[0].type &
OT_QWORD) {
2814 if (
op->operands[1].extended) {
2820 data[l++] = 0x90 +
op->operands[1].reg;
2822 }
else if (
op->operands[1].reg ==
X86R_EAX &&
2823 !
op->operands[1].extended &&
2828 }
else if (
op->operands[1].type &
OT_DWORD &&
2829 op->operands[0].extended) {
2831 }
else if (
op->operands[1].type &
OT_QWORD) {
2832 if (
op->operands[0].extended) {
2838 data[l++] = 0x90 +
op->operands[0].reg;
2840 }
else if (
op->operands[0].type &
OT_GPREG &&
2845 ut8 rex = 0x40 |
op->operands[0].extended |
op->operands[1].extended << 2 | !!(
op->operands[0].type &
OT_QWORD) << 3;
2855 reg =
op->operands[1].reg;
2856 rm =
op->operands[0].reg;
2859 data[l++] = mod_byte << 6 |
reg << 3 | rm;
2860 if (mod_byte > 0 && mod_byte < 3) {
2862 if (mod_byte == 2) {
2864 data[l++] =
offset >> 16;
2865 data[l++] =
offset >> 24;
2874 if (
a->bits == 64) {
2883 char *fcmov =
op->mnemonic + strlen(
"fcmov");
2884 switch (
op->operands_count) {
2888 if (!strcmp(fcmov,
"b")) {
2890 data[l++] = 0xc0 |
op->operands[1].reg;
2891 }
else if (!strcmp(fcmov,
"e")) {
2893 data[l++] = 0xc8 |
op->operands[1].reg;
2894 }
else if (!strcmp(fcmov,
"be")) {
2896 data[l++] = 0xd0 |
op->operands[1].reg;
2897 }
else if (!strcmp(fcmov,
"u")) {
2899 data[l++] = 0xd8 |
op->operands[1].reg;
2900 }
else if (!strcmp(fcmov,
"nb")) {
2902 data[l++] = 0xc0 |
op->operands[1].reg;
2903 }
else if (!strcmp(fcmov,
"ne")) {
2905 data[l++] = 0xc8 |
op->operands[1].reg;
2906 }
else if (!strcmp(fcmov,
"nbe")) {
2908 data[l++] = 0xd0 |
op->operands[1].reg;
2909 }
else if (!strcmp(fcmov,
"nu")) {
2911 data[l++] = 0xd8 |
op->operands[1].reg;
2927 switch (
op->operands_count) {
2931 data[l++] = 0xc0 |
op->operands[0].reg;
2944 switch (
op->operands_count) {
2948 data[l++] = 0x20 |
op->operands[0].regs[0];
2961 switch (
op->operands_count) {
2969 data[l++] = 0xc8 |
op->operands[0].reg;
2982 switch (
op->operands_count) {
2986 data[l++] = 0xe0 |
op->operands[0].reg;
3003 switch (
op->operands_count) {
3007 data[l++] = 0xe8 |
op->operands[0].reg;
3024 switch (
op->operands_count) {
3029 data[l++] = 0xc0 |
op->operands[0].reg;
3046 switch (
op->operands_count) {
3051 data[l++] = 0x00 |
op->operands[0].regs[0];
3052 }
else if (
op->operands[0].type &
OT_DWORD) {
3054 data[l++] = 0x00 |
op->operands[0].regs[0];
3070 switch (
op->operands_count) {
3075 data[l++] = 0x00 |
op->operands[0].regs[0];
3076 }
else if (
op->operands[0].type &
OT_DWORD) {
3078 data[l++] = 0x00 |
op->operands[0].regs[0];
3090 data[l++] = 0xc0 |
op->operands[1].reg;
3094 data[l++] = 0xc0 |
op->operands[0].reg;
3107 switch (
op->operands_count) {
3112 data[l++] = 0x10 |
op->operands[0].regs[0];
3113 }
else if (
op->operands[0].type &
OT_DWORD) {
3115 data[l++] = 0x10 |
op->operands[0].regs[0];
3131 switch (
op->operands_count) {
3136 data[l++] = 0x18 |
op->operands[0].regs[0];
3137 }
else if (
op->operands[0].type &
OT_DWORD) {
3139 data[l++] = 0x18 |
op->operands[0].regs[0];
3155 switch (
op->operands_count) {
3160 data[l++] = 0x00 |
op->operands[0].regs[0];
3161 }
else if (
op->operands[0].type &
OT_DWORD) {
3163 data[l++] = 0x00 |
op->operands[0].regs[0];
3164 }
else if (
op->operands[0].type &
OT_QWORD) {
3166 data[l++] = 0x28 |
op->operands[0].regs[0];
3182 switch (
op->operands_count) {
3187 data[l++] = 0x28 |
op->operands[0].regs[0];
3200 switch (
op->operands_count) {
3204 data[l++] = 0x20 |
op->operands[0].regs[0];
3217 switch (
op->operands_count) {
3222 data[l++] = 0x20 |
op->operands[0].regs[0];
3235 switch (
op->operands_count) {
3240 data[l++] = 0x30 |
op->operands[0].regs[0];
3253 switch (
op->operands_count) {
3258 data[l++] = 0x08 |
op->operands[0].regs[0];
3271 switch (
op->operands_count) {
3276 data[l++] = 0x00 |
op->operands[0].regs[0];
3289 switch (
op->operands_count) {
3294 data[l++] = 0x10 |
op->operands[0].regs[0];
3295 }
else if (
op->operands[0].type &
OT_DWORD) {
3297 data[l++] = 0x10 |
op->operands[0].regs[0];
3313 switch (
op->operands_count) {
3318 data[l++] = 0x18 |
op->operands[0].regs[0];
3319 }
else if (
op->operands[0].type &
OT_DWORD) {
3321 data[l++] = 0x18 |
op->operands[0].regs[0];
3322 }
else if (
op->operands[0].type &
OT_QWORD) {
3324 data[l++] = 0x38 |
op->operands[0].regs[0];
3340 switch (
op->operands_count) {
3345 data[l++] = 0x08 |
op->operands[0].regs[0];
3346 }
else if (
op->operands[0].type &
OT_DWORD) {
3348 data[l++] = 0x08 |
op->operands[0].regs[0];
3349 }
else if (
op->operands[0].type &
OT_QWORD) {
3351 data[l++] = 0x08 |
op->operands[0].regs[0];
3367 switch (
op->operands_count) {
3372 data[l++] = 0x30 |
op->operands[0].regs[0];
3385 switch (
op->operands_count) {
3389 data[l++] = 0x30 |
op->operands[0].regs[0];
3402 switch (
op->operands_count) {
3407 data[l++] = 0x30 |
op->operands[0].regs[0];
3408 }
else if (
op->operands[0].type &
OT_QWORD) {
3410 data[l++] = 0x30 |
op->operands[0].regs[0];
3422 data[l++] = 0xf0 |
op->operands[1].reg;
3426 data[l++] = 0xf8 |
op->operands[0].reg;
3439 switch (
op->operands_count) {
3448 data[l++] = 0xf8 |
op->operands[0].reg;
3461 switch (
op->operands_count) {
3466 data[l++] = 0x30 |
op->operands[0].regs[0];
3467 }
else if (
op->operands[0].type &
OT_WORD) {
3469 data[l++] = 0x30 |
op->operands[0].regs[0];
3485 switch (
op->operands_count) {
3490 data[l++] = 0x38 |
op->operands[0].regs[0];
3491 }
else if (
op->operands[0].type &
OT_QWORD) {
3493 data[l++] = 0x38 |
op->operands[0].regs[0];
3505 data[l++] = 0xf8 |
op->operands[1].reg;
3509 data[l++] = 0xf0 |
op->operands[0].reg;
3522 switch (
op->operands_count) {
3531 data[l++] = 0xf0 |
op->operands[0].reg;
3544 switch (
op->operands_count) {
3549 data[l++] = 0x38 |
op->operands[0].regs[0];
3550 }
else if (
op->operands[0].type &
OT_WORD) {
3552 data[l++] = 0x38 |
op->operands[0].regs[0];
3568 switch (
op->operands_count) {
3573 data[l++] = 0x08 |
op->operands[0].regs[0];
3574 }
else if (
op->operands[0].type &
OT_QWORD) {
3576 data[l++] = 0x08 |
op->operands[0].regs[0];
3588 data[l++] = 0xc8 |
op->operands[1].reg;
3592 data[l++] = 0xc8 |
op->operands[0].reg;
3605 switch (
op->operands_count) {
3614 data[l++] = 0xc8 |
op->operands[0].reg;
3627 switch (
op->operands_count) {
3632 data[l++] = 0x08 |
op->operands[0].regs[0];
3633 }
else if (
op->operands[0].type &
OT_WORD) {
3635 data[l++] = 0x08 |
op->operands[0].regs[0];
3651 switch (
op->operands_count) {
3656 data[l++] = 0x20 |
op->operands[0].regs[0];
3657 }
else if (
op->operands[0].type &
OT_QWORD) {
3659 data[l++] = 0x20 |
op->operands[0].regs[0];
3671 data[l++] = 0xe0 |
op->operands[1].reg;
3675 data[l++] = 0xe8 |
op->operands[0].reg;
3688 switch (
op->operands_count) {
3697 data[l++] = 0xe8 |
op->operands[0].reg;
3710 switch (
op->operands_count) {
3715 data[l++] = 0x20 |
op->operands[0].regs[0];
3716 }
else if (
op->operands[0].type &
OT_WORD) {
3718 data[l++] = 0x20 |
op->operands[0].regs[0];
3734 switch (
op->operands_count) {
3739 data[l++] = 0x28 |
op->operands[0].regs[0];
3740 }
else if (
op->operands[0].type &
OT_QWORD) {
3742 data[l++] = 0x28 |
op->operands[0].regs[0];
3754 data[l++] = 0xe8 |
op->operands[1].reg;
3758 data[l++] = 0xe0 |
op->operands[0].reg;
3771 switch (
op->operands_count) {
3780 data[l++] = 0xe0 |
op->operands[0].reg;
3793 switch (
op->operands_count) {
3798 data[l++] = 0x28 |
op->operands[0].regs[0];
3799 }
else if (
op->operands[0].type &
OT_WORD) {
3801 data[l++] = 0x28 |
op->operands[0].regs[0];
3817 switch (
op->operands_count) {
3822 data[l++] = 0x38 |
op->operands[0].regs[0];
3835 switch (
op->operands_count) {
3841 data[l++] = 0x38 |
op->operands[0].regs[0];
3854 switch (
op->operands_count) {
3859 data[l++] = 0x38 |
op->operands[0].regs[0];
3860 }
else if (
op->operands[0].type &
OT_GPREG &&
3877 switch (
op->operands_count) {
3883 data[l++] = 0x38 |
op->operands[0].regs[0];
3884 }
else if (
op->operands[0].type &
OT_GPREG &&
3902 switch (
op->operands_count) {
3907 data[l++] = 0x30 |
op->operands[0].regs[0];
3920 switch (
op->operands_count) {
3926 data[l++] = 0x30 |
op->operands[0].regs[0];
3939 switch (
op->operands_count) {
3945 data[l++] = 0x10 |
op->operands[0].regs[0];
3947 data[l++] = 0xd0 |
op->operands[0].reg;
3961 switch (
op->operands_count) {
3967 data[l++] = 0x30 |
op->operands[0].regs[0];
3969 data[l++] = 0xf0 |
op->operands[0].reg;
3983 switch (
op->operands_count) {
3988 data[l++] = 0x10 |
op->operands[0].regs[0];
4001 switch (
op->operands_count) {
4006 data[l++] = 0x18 |
op->operands[0].regs[0];
4019 switch (
op->operands_count) {
4024 data[l++] = 0x00 |
op->operands[0].regs[0];
4037 switch (
op->operands_count) {
4043 data[l++] = 0x18 |
op->operands[0].regs[0];
4056 switch (
op->operands_count) {
4062 data[l++] = 0x08 |
op->operands[0].regs[0];
4063 }
else if (
op->operands[0].type &
OT_GPREG &&
4067 data[l++] = 0xc8 |
op->operands[0].reg;
4080 switch (
op->operands_count) {
4085 data[l++] = 0x08 |
op->operands[0].regs[0];
4098 switch (
op->operands_count) {
4100 if (
a->bits == 64) {
4106 data[l++] = 0x00 |
op->operands[0].regs[0];
4108 data[l++] = 0xc0 |
op->operands[0].reg;
4119 switch (
op->operands_count) {
4121 if (
a->bits == 64) {
4127 data[l++] = 0x20 |
op->operands[0].regs[0];
4129 data[l++] = 0xe0 |
op->operands[0].reg;
4140 switch (
op->operands_count) {
4146 data[l++] = 0x20 |
op->operands[0].regs[0];
4148 data[l++] = 0xe0 |
op->operands[0].reg;
4162 switch (
op->operands_count) {
4168 data[l++] = 0x28 |
op->operands[0].regs[0];
4170 data[l++] = 0xe8 |
op->operands[0].reg;
4184 switch (
op->operands_count) {
4191 data[l++] = 0x30 |
op->operands[0].regs[0];
4204 switch (
op->operands_count) {
4211 data[l++] = 0x30 |
op->operands[0].regs[0];
4224 switch (
op->operands_count) {
4230 data[l++] = 0x30 |
op->operands[0].regs[0];
4243 switch (
op->operands_count) {
4249 data[l++] = 0x38 |
op->operands[0].regs[0];
4269 {
"aaa", 0,
NULL, 0x37, 1 },
4270 {
"aad", 0,
NULL, 0xd50a, 2 },
4271 {
"aam", 0,
opaam, 0 },
4272 {
"aas", 0,
NULL, 0x3f, 1 },
4273 {
"adc", 0, &
opadc, 0 },
4274 {
"add", 0, &
opadd, 0 },
4275 {
"adx", 0,
NULL, 0xd4, 1 },
4276 {
"amx", 0,
NULL, 0xd5, 1 },
4277 {
"and", 0, &
opand, 0 },
4278 {
"bsf", 0, &
opbs, 0 },
4279 {
"bsr", 0, &
opbs, 0 },
4281 {
"call", 0, &
opcall, 0 },
4282 {
"cbw", 0,
NULL, 0x6698, 2 },
4283 {
"cdq", 0,
NULL, 0x99, 1 },
4284 {
"cdqe", 0, &
opcdqe, 0 },
4285 {
"cwde", 0, &
opcdqe, 0 },
4286 {
"clc", 0,
NULL, 0xf8, 1 },
4287 {
"cld", 0,
NULL, 0xfc, 1 },
4289 {
"clgi", 0,
NULL, 0x0f01dd, 3 },
4290 {
"cli", 0,
NULL, 0xfa, 1 },
4291 {
"clts", 0,
NULL, 0x0f06, 2 },
4292 {
"cmc", 0,
NULL, 0xf5, 1 },
4293 {
"cmovo", 0, &
opcmov, 0 },
4294 {
"cmovno", 0, &
opcmov, 0 },
4295 {
"cmovb", 0, &
opcmov, 0 },
4296 {
"cmovc", 0, &
opcmov, 0 },
4297 {
"cmovnae", 0, &
opcmov, 0 },
4298 {
"cmovae", 0, &
opcmov, 0 },
4299 {
"cmovnb", 0, &
opcmov, 0 },
4300 {
"cmovnc", 0, &
opcmov, 0 },
4301 {
"cmove", 0, &
opcmov, 0 },
4302 {
"cmovz", 0, &
opcmov, 0 },
4303 {
"cmovne", 0, &
opcmov, 0 },
4304 {
"cmovnz", 0, &
opcmov, 0 },
4305 {
"cmovbe", 0, &
opcmov, 0 },
4306 {
"cmovna", 0, &
opcmov, 0 },
4307 {
"cmova", 0, &
opcmov, 0 },
4308 {
"cmovnbe", 0, &
opcmov, 0 },
4309 {
"cmovne", 0, &
opcmov, 0 },
4310 {
"cmovnz", 0, &
opcmov, 0 },
4311 {
"cmovs", 0, &
opcmov, 0 },
4312 {
"cmovns", 0, &
opcmov, 0 },
4313 {
"cmovp", 0, &
opcmov, 0 },
4314 {
"cmovpe", 0, &
opcmov, 0 },
4315 {
"cmovnp", 0, &
opcmov, 0 },
4316 {
"cmovpo", 0, &
opcmov, 0 },
4317 {
"cmovl", 0, &
opcmov, 0 },
4318 {
"cmovnge", 0, &
opcmov, 0 },
4319 {
"cmovge", 0, &
opcmov, 0 },
4320 {
"cmovnl", 0, &
opcmov, 0 },
4321 {
"cmovle", 0, &
opcmov, 0 },
4322 {
"cmovng", 0, &
opcmov, 0 },
4323 {
"cmovg", 0, &
opcmov, 0 },
4324 {
"cmovnle", 0, &
opcmov, 0 },
4325 {
"cmp", 0, &
opcmp, 0 },
4326 {
"cmpsb", 0,
NULL, 0xa6, 1 },
4327 {
"cmpsd", 0,
NULL, 0xa7, 1 },
4328 {
"cmpsw", 0,
NULL, 0x66a7, 2 },
4329 {
"cpuid", 0,
NULL, 0x0fa2, 2 },
4330 {
"cwd", 0,
NULL, 0x6699, 2 },
4331 {
"cwde", 0,
NULL, 0x98, 1 },
4332 {
"daa", 0,
NULL, 0x27, 1 },
4333 {
"das", 0,
NULL, 0x2f, 1 },
4334 {
"dec", 0, &
opdec, 0 },
4335 {
"div", 0, &
opdiv, 0 },
4336 {
"emms", 0,
NULL, 0x0f77, 2 },
4339 {
"f2xm1", 0,
NULL, 0xd9f0, 2 },
4340 {
"fabs", 0,
NULL, 0xd9e1, 2 },
4341 {
"fadd", 0, &
opfadd, 0 },
4343 {
"fbld", 0, &
opfbld, 0 },
4345 {
"fchs", 0,
NULL, 0xd9e0, 2 },
4346 {
"fclex", 0,
NULL, 0x9bdbe2, 3 },
4349 {
"fcmovbe", 0, &
opfcmov, 0 },
4351 {
"fcmovnb", 0, &
opfcmov, 0 },
4352 {
"fcmovne", 0, &
opfcmov, 0 },
4353 {
"fcmovnbe", 0, &
opfcmov, 0 },
4354 {
"fcmovnu", 0, &
opfcmov, 0 },
4355 {
"fcos", 0,
NULL, 0xd9ff, 2 },
4356 {
"fdecstp", 0,
NULL, 0xd9f6, 2 },
4357 {
"fdiv", 0, &
opfdiv, 0 },
4361 {
"femms", 0,
NULL, 0x0f0e, 2 },
4368 {
"fild", 0, &
opfild, 0 },
4370 {
"fincstp", 0,
NULL, 0xd9f7, 2 },
4371 {
"finit", 0,
NULL, 0x9bdbe3, 3 },
4372 {
"fist", 0, &
opfist, 0 },
4377 {
"fld1", 0,
NULL, 0xd9e8, 2 },
4380 {
"fldl2t", 0,
NULL, 0xd9e9, 2 },
4381 {
"fldl2e", 0,
NULL, 0xd9ea, 2 },
4382 {
"fldlg2", 0,
NULL, 0xd9ec, 2 },
4383 {
"fldln2", 0,
NULL, 0xd9ed, 2 },
4384 {
"fldpi", 0,
NULL, 0xd9eb, 2 },
4385 {
"fldz", 0,
NULL, 0xd9ee, 2 },
4386 {
"fmul", 0, &
opfmul, 0 },
4388 {
"fnclex", 0,
NULL, 0xdbe2, 2 },
4389 {
"fninit", 0,
NULL, 0xdbe3, 2 },
4390 {
"fnop", 0,
NULL, 0xd9d0, 2 },
4395 {
"fpatan", 0,
NULL, 0xd9f3, 2 },
4396 {
"fprem", 0,
NULL, 0xd9f8, 2 },
4397 {
"fprem1", 0,
NULL, 0xd9f5, 2 },
4398 {
"fptan", 0,
NULL, 0xd9f2, 2 },
4399 {
"frndint", 0,
NULL, 0xd9fc, 2 },
4402 {
"fscale", 0,
NULL, 0xd9fd, 2 },
4403 {
"fsin", 0,
NULL, 0xd9fe, 2 },
4404 {
"fsincos", 0,
NULL, 0xd9fb, 2 },
4405 {
"fsqrt", 0,
NULL, 0xd9fa, 2 },
4409 {
"fsub", 0, &
opfsub, 0 },
4413 {
"ftst", 0,
NULL, 0xd9e4, 2 },
4416 {
"fucompp", 0,
NULL, 0xdae9, 2 },
4417 {
"fwait", 0,
NULL, 0x9b, 1 },
4418 {
"fxam", 0,
NULL, 0xd9e5, 2 },
4419 {
"fxch", 0, &
opfxch, 0 },
4422 {
"fxtract", 0,
NULL, 0xd9f4, 2 },
4423 {
"fyl2x", 0,
NULL, 0xd9f1, 2 },
4424 {
"fyl2xp1", 0,
NULL, 0xd9f9, 2 },
4425 {
"getsec", 0,
NULL, 0x0f37, 2 },
4426 {
"hlt", 0,
NULL, 0xf4, 1 },
4427 {
"idiv", 0, &
opidiv, 0 },
4428 {
"imul", 0, &
opimul, 0 },
4429 {
"in", 0, &
opin, 0 },
4430 {
"inc", 0, &
opinc, 0 },
4431 {
"ins", 0,
NULL, 0x6d, 1 },
4432 {
"insb", 0,
NULL, 0x6c, 1 },
4433 {
"insd", 0,
NULL, 0x6d, 1 },
4434 {
"insw", 0,
NULL, 0x666d, 2 },
4435 {
"int", 0, &
opint, 0 },
4436 {
"int1", 0,
NULL, 0xf1, 1 },
4437 {
"int3", 0,
NULL, 0xcc, 1 },
4438 {
"into", 0,
NULL, 0xce, 1 },
4439 {
"invd", 0,
NULL, 0x0f08, 2 },
4440 {
"iret", 0,
NULL, 0x66cf, 2 },
4441 {
"iretd", 0,
NULL, 0xcf, 1 },
4442 {
"ja", 0, &
opjc, 0 },
4443 {
"jae", 0, &
opjc, 0 },
4444 {
"jb", 0, &
opjc, 0 },
4445 {
"jbe", 0, &
opjc, 0 },
4446 {
"jc", 0, &
opjc, 0 },
4447 {
"je", 0, &
opjc, 0 },
4448 {
"jg", 0, &
opjc, 0 },
4449 {
"jge", 0, &
opjc, 0 },
4450 {
"jl", 0, &
opjc, 0 },
4451 {
"jle", 0, &
opjc, 0 },
4452 {
"jmp", 0, &
opjc, 0 },
4453 {
"jna", 0, &
opjc, 0 },
4454 {
"jnae", 0, &
opjc, 0 },
4455 {
"jnb", 0, &
opjc, 0 },
4456 {
"jnbe", 0, &
opjc, 0 },
4457 {
"jnc", 0, &
opjc, 0 },
4458 {
"jne", 0, &
opjc, 0 },
4459 {
"jng", 0, &
opjc, 0 },
4460 {
"jnge", 0, &
opjc, 0 },
4461 {
"jnl", 0, &
opjc, 0 },
4462 {
"jnle", 0, &
opjc, 0 },
4463 {
"jno", 0, &
opjc, 0 },
4464 {
"jnp", 0, &
opjc, 0 },
4465 {
"jns", 0, &
opjc, 0 },
4466 {
"jnz", 0, &
opjc, 0 },
4467 {
"jo", 0, &
opjc, 0 },
4468 {
"jp", 0, &
opjc, 0 },
4469 {
"jpe", 0, &
opjc, 0 },
4470 {
"jpo", 0, &
opjc, 0 },
4471 {
"js", 0, &
opjc, 0 },
4472 {
"jz", 0, &
opjc, 0 },
4473 {
"lahf", 0,
NULL, 0x9f, 1 },
4474 {
"lea", 0, &
oplea, 0 },
4475 {
"leave", 0,
NULL, 0xc9, 1 },
4476 {
"les", 0, &
oples, 0 },
4477 {
"lfence", 0,
NULL, 0x0faee8, 3 },
4478 {
"lgdt", 0, &
oplgdt, 0 },
4479 {
"lidt", 0, &
oplidt, 0 },
4480 {
"lldt", 0, &
oplldt, 0 },
4481 {
"lmsw", 0, &
oplmsw, 0 },
4482 {
"lodsb", 0,
NULL, 0xac, 1 },
4483 {
"lodsd", 0,
NULL, 0xad, 1 },
4484 {
"lodsw", 0,
NULL, 0x66ad, 2 },
4485 {
"loop", 0, &
oploop, 0 },
4486 {
"mfence", 0,
NULL, 0x0faef0, 3 },
4487 {
"monitor", 0,
NULL, 0x0f01c8, 3 },
4488 {
"mov", 0, &
opmov, 0 },
4489 {
"movsb", 0,
NULL, 0xa4, 1 },
4490 {
"movsd", 0,
NULL, 0xa5, 1 },
4491 {
"movsw", 0,
NULL, 0x66a5, 2 },
4492 {
"movzx", 0, &
opmovx, 0 },
4493 {
"movsx", 0, &
opmovx, 0 },
4495 {
"mul", 0, &
opmul, 0 },
4496 {
"mwait", 0,
NULL, 0x0f01c9, 3 },
4497 {
"neg", 0, &
opneg, 0 },
4498 {
"nop", 0,
NULL, 0x90, 1 },
4499 {
"not", 0, &
opnot, 0 },
4500 {
"or", 0, &
opor, 0 },
4501 {
"out", 0, &
opout, 0 },
4502 {
"outsb", 0,
NULL, 0x6e, 1 },
4503 {
"outs", 0,
NULL, 0x6f, 1 },
4504 {
"outsd", 0,
NULL, 0x6f, 1 },
4505 {
"outsw", 0,
NULL, 0x666f, 2 },
4506 {
"pop", 0, &
oppop, 0 },
4507 {
"popa", 1,
NULL, 0x61, 1 },
4508 {
"popad", 1,
NULL, 0x61, 1 },
4509 {
"popal", 1,
NULL, 0x61, 1 },
4510 {
"popaw", 1,
NULL, 0x6661, 2 },
4511 {
"popfd", 1,
NULL, 0x9d, 1 },
4512 {
"prefetch", 0,
NULL, 0x0f0d, 2 },
4513 {
"push", 0, &
oppush, 0 },
4514 {
"pusha", 1,
NULL, 0x60, 1 },
4515 {
"pushad", 1,
NULL, 0x60, 1 },
4516 {
"pushal", 1,
NULL, 0x60, 1 },
4517 {
"pushfd", 0,
NULL, 0x9c, 1 },
4520 {
"rep", 0, &
oprep, 0 },
4521 {
"repe", 0, &
oprep, 0 },
4522 {
"repne", 0, &
oprep, 0 },
4523 {
"repz", 0, &
oprep, 0 },
4524 {
"repnz", 0, &
oprep, 0 },
4525 {
"rdmsr", 0,
NULL, 0x0f32, 2 },
4526 {
"rdpmc", 0,
NULL, 0x0f33, 2 },
4527 {
"rdtsc", 0,
NULL, 0x0f31, 2 },
4528 {
"rdtscp", 0,
NULL, 0x0f01f9, 3 },
4529 {
"ret", 0, &
opret, 0 },
4530 {
"retf", 0, &
opretf, 0 },
4531 {
"retw", 0,
NULL, 0x66c3, 2 },
4534 {
"rsm", 0,
NULL, 0x0faa, 2 },
4535 {
"sahf", 0,
NULL, 0x9e, 1 },
4537 {
"salc", 0,
NULL, 0xd6, 1 },
4539 {
"sbb", 0, &
opsbb, 0 },
4540 {
"scasb", 0,
NULL, 0xae, 1 },
4541 {
"scasd", 0,
NULL, 0xaf, 1 },
4542 {
"scasw", 0,
NULL, 0x66af, 2 },
4543 {
"seto", 0, &
opset, 0 },
4544 {
"setno", 0, &
opset, 0 },
4545 {
"setb", 0, &
opset, 0 },
4546 {
"setnae", 0, &
opset, 0 },
4547 {
"setc", 0, &
opset, 0 },
4548 {
"setnb", 0, &
opset, 0 },
4549 {
"setae", 0, &
opset, 0 },
4550 {
"setnc", 0, &
opset, 0 },
4551 {
"setz", 0, &
opset, 0 },
4552 {
"sete", 0, &
opset, 0 },
4553 {
"setnz", 0, &
opset, 0 },
4554 {
"setne", 0, &
opset, 0 },
4555 {
"setbe", 0, &
opset, 0 },
4556 {
"setna", 0, &
opset, 0 },
4557 {
"setnbe", 0, &
opset, 0 },
4558 {
"seta", 0, &
opset, 0 },
4559 {
"sets", 0, &
opset, 0 },
4560 {
"setns", 0, &
opset, 0 },
4561 {
"setp", 0, &
opset, 0 },
4562 {
"setpe", 0, &
opset, 0 },
4563 {
"setnp", 0, &
opset, 0 },
4564 {
"setpo", 0, &
opset, 0 },
4565 {
"setl", 0, &
opset, 0 },
4566 {
"setnge", 0, &
opset, 0 },
4567 {
"setnl", 0, &
opset, 0 },
4568 {
"setge", 0, &
opset, 0 },
4569 {
"setle", 0, &
opset, 0 },
4570 {
"setng", 0, &
opset, 0 },
4571 {
"setnle", 0, &
opset, 0 },
4572 {
"setg", 0, &
opset, 0 },
4573 {
"sfence", 0,
NULL, 0x0faef8, 3 },
4574 {
"sgdt", 0, &
opsgdt, 0 },
4577 {
"sidt", 0, &
opsidt, 0 },
4578 {
"sldt", 0, &
opsldt, 0 },
4579 {
"smsw", 0, &
opsmsw, 0 },
4580 {
"stc", 0,
NULL, 0xf9, 1 },
4581 {
"std", 0,
NULL, 0xfd, 1 },
4582 {
"stgi", 0,
NULL, 0x0f01dc, 3 },
4583 {
"sti", 0,
NULL, 0xfb, 1 },
4585 {
"stosb", 0, &
opstos, 0 },
4586 {
"stosd", 0, &
opstos, 0 },
4587 {
"stosw", 0, &
opstos, 0 },
4588 {
"str", 0, &
opstr, 0 },
4589 {
"sub", 0, &
opsub, 0 },
4590 {
"swapgs", 0,
NULL, 0x0f1ff8, 3 },
4591 {
"syscall", 0,
NULL, 0x0f05, 2 },
4592 {
"sysenter", 0,
NULL, 0x0f34, 2 },
4593 {
"sysexit", 0,
NULL, 0x0f35, 2 },
4594 {
"sysret", 0,
NULL, 0x0f07, 2 },
4595 {
"ud2", 0,
NULL, 0x0f0b, 2 },
4596 {
"verr", 0, &
opverr, 0 },
4597 {
"verw", 0, &
opverw, 0 },
4598 {
"vmcall", 0,
NULL, 0x0f01c1, 3 },
4600 {
"vmlaunch", 0,
NULL, 0x0f01c2, 3 },
4601 {
"vmload", 0,
NULL, 0x0f01da, 3 },
4602 {
"vmmcall", 0,
NULL, 0x0f01d9, 3 },
4605 {
"vmresume", 0,
NULL, 0x0f01c3, 3 },
4606 {
"vmrun", 0,
NULL, 0x0f01d8, 3 },
4607 {
"vmsave", 0,
NULL, 0x0f01db, 3 },
4608 {
"vmxoff", 0,
NULL, 0x0f01c4, 3 },
4609 {
"vmxon", 0, &
opvmon, 0 },
4610 {
"vzeroall", 0,
NULL, 0xc5fc77, 3 },
4611 {
"vzeroupper", 0,
NULL, 0xc5f877, 3 },
4612 {
"wait", 0,
NULL, 0x9b, 1 },
4613 {
"wbinvd", 0,
NULL, 0x0f09, 2 },
4614 {
"wrmsr", 0,
NULL, 0x0f30, 2 },
4615 {
"xadd", 0, &
opxadd, 0 },
4616 {
"xchg", 0, &
opxchg, 0 },
4617 {
"xgetbv", 0,
NULL, 0x0f01d0, 3 },
4618 {
"xlatb", 0,
NULL, 0xd7, 1 },
4619 {
"xor", 0, &
opxor, 0 },
4620 {
"xsetbv", 0,
NULL, 0x0f01d1, 3 },
4621 {
"test", 0, &
optest, 0 },
4622 {
"null", 0,
NULL, 0, 0 }
4626 if (*begin > strlen(
str)) {
4660 int n = atoi(token + 3);
4661 return (
n >= 0 &&
n <= 15);
4668 const bool parn = token[2] ==
'(';
4674 if (
n >=
'0' &&
n <=
'7') {
4676 if (token[3] !=
')') {
4689 const bool parn = token[2] ==
'(';
4695 if (
n >=
'0' &&
n <=
'7') {
4697 if (token[3] !=
')') {
4714 const char *
regs[] = {
"eax",
"ecx",
"edx",
"ebx",
"esp",
"ebp",
"esi",
"edi",
"eip",
NULL };
4715 const char *regsext[] = {
"r8d",
"r9d",
"r10d",
"r11d",
"r12d",
"r13d",
"r14d",
"r15d",
NULL };
4716 const char *regs8[] = {
"al",
"cl",
"dl",
"bl",
"ah",
"ch",
"dh",
"bh",
NULL };
4717 const char *regs16[] = {
"ax",
"cx",
"dx",
"bx",
"sp",
"bp",
"si",
"di",
NULL };
4718 const char *regs64[] = {
"rax",
"rcx",
"rdx",
"rbx",
"rsp",
"rbp",
"rsi",
"rdi",
"rip",
NULL };
4719 const char *regs64ext[] = {
"r8",
"r9",
"r10",
"r11",
"r12",
"r13",
"r14",
"r15",
NULL };
4720 const char *sregs[] = {
"es",
"cs",
"ss",
"ds",
"fs",
"gs",
NULL };
4721 const char *cregs[] = {
"cr0",
"cr1",
"cr2",
"cr3",
"cr4",
"cr5",
"cr6",
"cr7",
NULL };
4722 const char *dregs[] = {
"dr0",
"dr1",
"dr2",
"dr3",
"dr4",
"dr5",
"dr6",
"dr7",
NULL };
4733 if (
length == 3 && token[0] ==
'e') {
4742 if (
length == 3 && token[0] ==
'c') {
4743 for (
i = 0; cregs[
i];
i++) {
4751 if (
length == 3 && token[0] ==
'd') {
4752 for (
i = 0; cregs[
i];
i++) {
4760 if (token[1] ==
'l' || token[1] ==
'h') {
4761 for (
i = 0; regs8[
i];
i++) {
4768 for (
i = 0; regs16[
i];
i++) {
4775 for (
i = 0; sregs[
i];
i++) {
4782 if (token[0] ==
'r') {
4783 for (
i = 0; regs64[
i];
i++) {
4790 for (
i = 0; regs64ext[
i];
i++) {
4797 for (
i = 0; regsext[
i];
i++) {
4830 RZ_LOG_ERROR(
"assembler: x86.nz: expected register number but found '%s'\n",
str + *
pos);
4836 RZ_LOG_ERROR(
"assembler: x86.nz: register index is too large\n");
4854 char *
c = strchr(
str + nextpos,
':');
4857 c = strchr(
str + nextpos,
'[');
4863 op->regs[reg_index] =
op->reg;
4865 op->offset_sign = 1;
4866 char *
p = strchr(
str + nextpos,
'-');
4868 op->offset_sign = -1;
4872 op->offset =
op->scale[reg_index];
4877 size_t pos, nextpos = 0;
4880 bool explicit_size =
false;
4885 while (size_token) {
4895 explicit_size =
true;
4899 explicit_size =
true;
4903 explicit_size =
true;
4907 explicit_size =
true;
4911 explicit_size =
true;
4915 explicit_size =
true;
4930 op->offset =
op->scale[0] =
op->scale[1] = 0;
4934 bool first_reg =
true;
4935 while (
str[
pos] !=
']') {
4936 if (
pos > nextpos) {
4949 if (reg_index < 2) {
4950 op->regs[reg_index] =
reg;
4951 op->scale[reg_index] = temp;
4956 if (reg_index < 2) {
4962 }
else if (
str[
pos] ==
'*') {
4981 op->extended =
false;
4983 op->extended =
true;
4989 }
else if (
reg > 8) {
4994 op->type = reg_type;
5000 if (!explicit_size) {
5001 op->type |= reg_type;
5003 op->reg_size = reg_type;
5004 op->explicit_size = explicit_size;
5011 char *
p = strchr(
str,
'+');
5012 op->offset_sign = 1;
5014 p = strchr(
str,
'-');
5016 op->offset_sign = -1;
5020 char *plus = strchr(
str,
'+');
5021 char *minus = strchr(
str,
'-');
5022 char *closeB = strchr(
str,
']');
5023 if (plus && minus && plus < closeB && minus < closeB) {
5024 op->offset_sign = -1;
5042 op->is_good_flag =
false;
5050 op->extended =
false;
5052 op->extended =
true;
5060 op->is_good_flag =
false;
5061 if (
a->num &&
a->num->value == 0) {
5067 op->is_good_flag =
true;
5070 char *
p = strchr(
str,
'-');
5084 char *
p = strchr(
str,
'-');
5096 out->has_bnd =
false;
5097 bool isrepop =
false;
5098 if (!strncmp(
op,
"bnd ", 4)) {
5099 out->has_bnd =
true;
5102 char *
args = strchr(
op,
' ');
5104 out->operands[0].type =
out->operands[1].type = 0;
5105 out->operands[0].extended =
out->operands[1].extended =
false;
5108 out->operands[0].immediate =
out->operands[1].immediate = 0;
5109 out->operands[0].sign =
out->operands[1].sign = 1;
5110 out->operands[0].is_good_flag =
out->operands[1].is_good_flag =
true;
5111 out->is_short =
false;
5112 out->operands_count = 0;
5119 out->is_short =
true;
5122 if (!strncmp(
out->mnemonic,
"rep", 3)) {
5126 out->operands_count = 1;
5134 out->operands_count++;
5153 if (!strcmp(
op->mnemonic,
"rep") ||
5154 !strcmp(
op->mnemonic,
"repe") ||
5155 !strcmp(
op->mnemonic,
"repz")) {
5157 }
else if (!strcmp(
op->mnemonic,
"repne") ||
5158 !strcmp(
op->mnemonic,
"repnz")) {
5166 if (lt_ptr->
opcode > 0) {
5167 if (lt_ptr->
only_x32 &&
a->bits == 64) {
5172 int i = lt_ptr->
size - 1;
5173 for (;
i >= 0;
i--) {
5174 data[
i + l] = opcode & 0xff;
5178 return l + lt_ptr->
size;
5186 retval = lt_ptr->
opdo(
a, data, &instr);
5203 ut8 __data[32] = { 0 };
5210 strncpy(
op,
str,
sizeof(
op) - 1);
5211 op[
sizeof(
op) - 1] =
'\0';
5215 if (lt_ptr->
opcode > 0) {
5216 if (!lt_ptr->
only_x32 ||
a->bits != 64) {
5218 int i = lt_ptr->
size - 1;
5219 for (;
i >= 0;
i--) {
5220 data[
i] = opcode & 0xff;
5223 retval = lt_ptr->
size;
5231 retval = lt_ptr->
opdo(
a, data, &instr);
5251 .desc =
"x86 handmade assembler",
5254 .bits = 16 | 32 | 64,
5259 #ifndef RZ_PLUGIN_INCORE
static enum map_type last_type
RZ_API void rz_asm_op_set_buf(RzAsmOp *op, const ut8 *buf, int len)
static ut32 reg_bits(arm_reg reg)
static int opmovabs(RzAsm *a, ut8 *data, const Opcode *op)
#define is_valid_registers(op)
static int opvmon(RzAsm *a, ut8 *data, const Opcode *op)
const ut8 SEG_REG_PREFIXES[]
static int opout(RzAsm *a, ut8 *data, const Opcode *op)
static ut64 getnum(RzAsm *a, const char *s)
static int oplea(RzAsm *a, ut8 *data, const Opcode *op)
static x86newTokenType getToken(const char *str, size_t *begin, size_t *end)
static int opretf(RzAsm *a, ut8 *data, const Opcode *op)
static int opfiadd(RzAsm *a, ut8 *data, const Opcode *op)
static int opfsubr(RzAsm *a, ut8 *data, const Opcode *op)
static int opfucom(RzAsm *a, ut8 *data, const Opcode *op)
enum tokentype_t x86newTokenType
static int opverr(RzAsm *a, ut8 *data, const Opcode *op)
static int opfxsave(RzAsm *a, ut8 *data, const Opcode *op)
static int opor(RzAsm *a, ut8 *data, const Opcode *op)
static int opfldenv(RzAsm *a, ut8 *data, const Opcode *op)
static int opmov(RzAsm *a, ut8 *data, const Opcode *op)
static int opfrstor(RzAsm *a, ut8 *data, const Opcode *op)
static int process_16bit_group_1(RzAsm *a, ut8 *data, const Opcode *op, int op1)
static int opin(RzAsm *a, ut8 *data, const Opcode *op)
static int process_group_1(RzAsm *a, ut8 *data, const Opcode *op)
static int oplidt(RzAsm *a, ut8 *data, const Opcode *op)
static int opfcmov(RzAsm *a, ut8 *data, const Opcode *op)
static int opfisubr(RzAsm *a, ut8 *data, const Opcode *op)
static int opfnstsw(RzAsm *a, ut8 *data, const Opcode *op)
RzAsmPlugin rz_asm_plugin_x86_nz
static int opfmulp(RzAsm *a, ut8 *data, const Opcode *op)
static int opdec(RzAsm *a, ut8 *data, const Opcode *op)
static int opret(RzAsm *a, ut8 *data, const Opcode *op)
static int opfstsw(RzAsm *a, ut8 *data, const Opcode *op)
static int opxor(RzAsm *a, ut8 *data, const Opcode *op)
static int opand(RzAsm *a, ut8 *data, const Opcode *op)
static int opfmul(RzAsm *a, ut8 *data, const Opcode *op)
static int opsbb(RzAsm *a, ut8 *data, const Opcode *op)
static int opfimul(RzAsm *a, ut8 *data, const Opcode *op)
static int opsmsw(RzAsm *a, ut8 *data, const Opcode *op)
static int opfucomp(RzAsm *a, ut8 *data, const Opcode *op)
static int opfnstcw(RzAsm *a, ut8 *data, const Opcode *op)
static int opfdivp(RzAsm *a, ut8 *data, const Opcode *op)
static int parseOperand(RzAsm *a, const char *str, Operand *op, bool isrepop)
static int opsub(RzAsm *a, ut8 *data, const Opcode *op)
static int opxadd(RzAsm *a, ut8 *data, const Opcode *op)
static int endbr32(RzAsm *a, ut8 *data, const Opcode *op)
static int opfxrstor(RzAsm *a, ut8 *data, const Opcode *op)
static int opfnsave(RzAsm *a, ut8 *data, const Opcode *op)
static int opficom(RzAsm *a, ut8 *data, const Opcode *op)
static Register parseReg(RzAsm *a, const char *str, size_t *pos, ut32 *type)
static int opverw(RzAsm *a, ut8 *data, const Opcode *op)
static int opficomp(RzAsm *a, ut8 *data, const Opcode *op)
static int opneg(RzAsm *a, ut8 *data, const Opcode *op)
static int opfldcw(RzAsm *a, ut8 *data, const Opcode *op)
static int opfdivrp(RzAsm *a, ut8 *data, const Opcode *op)
static int opmovx(RzAsm *a, ut8 *data, const Opcode *op)
static int opvmclear(RzAsm *a, ut8 *data, const Opcode *op)
static int opadd(RzAsm *a, ut8 *data, const Opcode *op)
static int is_al_reg(const Operand *op)
static int endbr64(RzAsm *a, ut8 *data, const Opcode *op)
static bool is_st_register(const char *token)
static int assemble(RzAsm *a, RzAsmOp *ao, const char *str)
static int oprep(RzAsm *a, ut8 *data, const Opcode *op)
static int opfistp(RzAsm *a, ut8 *data, const Opcode *op)
static int opbswap(RzAsm *a, ut8 *data, const Opcode *op)
static int opfsubrp(RzAsm *a, ut8 *data, const Opcode *op)
RZ_API RzLibStruct rizin_plugin
static int opfild(RzAsm *a, ut8 *data, const Opcode *op)
static int opsidt(RzAsm *a, ut8 *data, const Opcode *op)
static int opfsub(RzAsm *a, ut8 *data, const Opcode *op)
static int oplgdt(RzAsm *a, ut8 *data, const Opcode *op)
static int opxchg(RzAsm *a, ut8 *data, const Opcode *op)
static int opnot(RzAsm *a, ut8 *data, const Opcode *op)
static void parse_segment_offset(RzAsm *a, const char *str, size_t *pos, Operand *op, int reg_index)
static int opinc(RzAsm *a, ut8 *data, const Opcode *op)
static int oppush(RzAsm *a, ut8 *data, const Opcode *op)
static int opfxch(RzAsm *a, ut8 *data, const Opcode *op)
static int opfsave(RzAsm *a, ut8 *data, const Opcode *op)
static bool is_xmm_register(const char *token)
static int oples(RzAsm *a, ut8 *data, const Opcode *op)
static int opsgdt(RzAsm *a, ut8 *data, const Opcode *op)
static int oppop(RzAsm *a, ut8 *data, const Opcode *op)
static int oploop(RzAsm *a, ut8 *data, const Opcode *op)
struct lookup_t LookupTable
static int opfisub(RzAsm *a, ut8 *data, const Opcode *op)
static int opfbstp(RzAsm *a, ut8 *data, const Opcode *op)
static int opidiv(RzAsm *a, ut8 *data, const Opcode *op)
static int opffree(RzAsm *a, ut8 *data, const Opcode *op)
static int opaam(RzAsm *a, ut8 *data, const Opcode *op)
static int opjc(RzAsm *a, ut8 *data, const Opcode *op)
static int opvmptrld(RzAsm *a, ut8 *data, const Opcode *op)
static int opint(RzAsm *a, ut8 *data, const Opcode *op)
static int opclflush(RzAsm *a, ut8 *data, const Opcode *op)
static int opfist(RzAsm *a, ut8 *data, const Opcode *op)
static int process_group_2(RzAsm *a, ut8 *data, const Opcode *op)
static int opmul(RzAsm *a, ut8 *data, const Opcode *op)
static bool is_mm_register(const char *token)
static int opfidivr(RzAsm *a, ut8 *data, const Opcode *op)
static int opstmxcsr(RzAsm *a, ut8 *data, const Opcode *op)
static int opcall(RzAsm *a, ut8 *data, const Opcode *op)
static bool is_debug_or_control(Operand op)
static int opsldt(RzAsm *a, ut8 *data, const Opcode *op)
static int opimul(RzAsm *a, ut8 *data, const Opcode *op)
static int opcmp(RzAsm *a, ut8 *data, const Opcode *op)
static int opadc(RzAsm *a, ut8 *data, const Opcode *op)
static int opfidiv(RzAsm *a, ut8 *data, const Opcode *op)
static int opfdiv(RzAsm *a, ut8 *data, const Opcode *op)
static int opvmptrst(RzAsm *a, ut8 *data, const Opcode *op)
static int opfnstenv(RzAsm *a, ut8 *data, const Opcode *op)
static int process_1byte_op(RzAsm *a, ut8 *data, const Opcode *op, int op1)
static int opstr(RzAsm *a, ut8 *data, const Opcode *op)
static int opbs(RzAsm *a, ut8 *data, const Opcode *op)
static int opset(RzAsm *a, ut8 *data, const Opcode *op)
static int parseOpcode(RzAsm *a, const char *op, Opcode *out)
static int opfstcw(RzAsm *a, ut8 *data, const Opcode *op)
static int opfsubp(RzAsm *a, ut8 *data, const Opcode *op)
static int opcdqe(RzAsm *a, ut8 *data, const Opcode *op)
static int opfbld(RzAsm *a, ut8 *data, const Opcode *op)
static int oplmsw(RzAsm *a, ut8 *data, const Opcode *op)
static int opcmov(RzAsm *a, ut8 *data, const Opcode *op)
static int opfisttp(RzAsm *a, ut8 *data, const Opcode *op)
static int opfstenv(RzAsm *a, ut8 *data, const Opcode *op)
static int oplldt(RzAsm *a, ut8 *data, const Opcode *op)
static int opstos(RzAsm *a, ut8 *data, const Opcode *op)
static ut8 getsib(const ut8 sib)
static int optest(RzAsm *a, ut8 *data, const Opcode *op)
static int opfaddp(RzAsm *a, ut8 *data, const Opcode *op)
static int opdiv(RzAsm *a, ut8 *data, const Opcode *op)
static int opfdivr(RzAsm *a, ut8 *data, const Opcode *op)
static int opfadd(RzAsm *a, ut8 *data, const Opcode *op)
int bits(struct state *s, int need)
const lzma_allocator const uint8_t size_t uint8_t * out
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
RZ_API RzFlagItem * rz_flag_get(RzFlag *f, const char *name)
RZ_API void Ht_() free(HtName_(Ht) *ht)
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * malloc(size_t size)
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
#define RZ_LOG_ERROR(fmtstr,...)
RZ_API ut64 rz_num_math(RzNum *num, const char *str)
RZ_API int rz_str_casecmp(const char *dst, const char *orig)
RZ_API char * rz_str_ndup(RZ_NULLABLE const char *ptr, int len)
Create new copy of string ptr limited to size len.
RZ_API int rz_str_ncasecmp(const char *dst, const char *orig, size_t n)
#define RZ_SYS_ENDIAN_LITTLE
int(* opdo)(RzAsm *, ut8 *, const Opcode *)
char rep_op[MAX_REPOP_LENGTH]
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
int read(izstream &zs, T *x, Items items)