1 // Copyright (C) 2004, Matt Conover (mconover@gmail.com) 2 #ifndef X86_DISASM_H 3 #define X86_DISASM_H 4 #ifdef __cplusplus 5 extern "C" { 6 #endif 7 8 // NOTE: the processor may actually accept less than this amount (officially 15) 9 // #define AMD64_MAX_INSTRUCTION_LEN 15 // theoretical max 25=5+2+1+1+8+8 10 #define AMD64_MAX_PREFIX_LENGTH 5 // 4 legacy + 1 rex 11 #define AMD64_MAX_ADDRESS_LENGTH 18 // modrm + sib + 8 byte displacement + 8 byte immediate value 12 13 // NOTE: the processor may actually accept less than this amount (officially 15) 14 #define X86_MAX_INSTRUCTION_LEN 15 // theoretical 16=4+2+1+1+4+4 15 #define X86_MAX_PREFIX_LENGTH 4 16 #define X86_MAX_OPCODE_LENGTH 3 // third byte is either a suffix or prefix 17 #define X86_MAX_ADDRESS_LENGTH 10 // modrm + sib + 4 byte displacement + 4 byte immediate value 18 #define X86_MAX_OPERANDS 3 19 20 #define X86_PREFIX(a) ((a)->MnemonicFlags == ITYPE_EXT_PREFIX) 21 #define X86_SPECIAL_EXTENSION(a) ((a)->MnemonicFlags & (ITYPE_EXT_MODRM|ITYPE_EXT_FPU|ITYPE_EXT_SUFFIX|ITYPE_EXT_64)) 22 #define X86_EXTENDED_OPCODE(a) ((a)->Table) 23 #define X86_INVALID(a) (!(a)->MnemonicFlags && !(a)->Table) 24 #define X86_OPERAND_COUNT(a) ((a)->OperandFlags[0] ? ((a)->OperandFlags[1] ? ((a)->OperandFlags[2] ? 3 : 2) : 1) : 0) 25 #define X86_GET_CATEGORY(p) ((p)->MnemonicFlags & ITYPE_GROUP_MASK) 26 #define X86_GET_TYPE(p) ((p)->MnemonicFlags & ITYPE_TYPE_MASK) 27 28 // Various instructions being specially decoded 29 #define X86_TWO_BYTE_OPCODE 0x0f 30 #define PREFIX_SEGMENT_OVERRIDE_ES 0x26 31 #define PREFIX_SEGMENT_OVERRIDE_CS 0x2e 32 #define PREFIX_BRANCH_NOT_TAKEN 0x2e // used only with conditional jumps 33 #define PREFIX_SEGMENT_OVERRIDE_SS 0x36 34 #define PREFIX_SEGMENT_OVERRIDE_DS 0x3e 35 #define PREFIX_BRANCH_TAKEN 0x3e // used only with conditional jumps 36 #define PREFIX_SEGMENT_OVERRIDE_FS 0x64 37 #define PREFIX_SEGMENT_OVERRIDE_GS 0x65 38 #define PREFIX_OPERAND_SIZE 0x66 39 #define PREFIX_ADDRESS_SIZE 0x67 40 #define PREFIX_LOCK 0xf0 41 #define PREFIX_REPNE 0xf2 42 #define PREFIX_REP 0xf3 43 44 ////////////////////////////////////////////////////////////////// 45 // Implicit operand handling 46 ////////////////////////////////////////////////////////////////// 47 48 #define X86_AMODE_MASK 0x00FF0000 // bits 16-23 (AMODE_*) 49 #define X86_OPFLAGS_MASK 0x0000FF80 // bits 7-15 (OPTYPE_*) 50 #define X86_OPTYPE_MASK 0xFF0000FF // bits 0-7 (OPTYPE_* below + OP_REG) and 24-31 (OPTYPE_* above) 51 52 #define OPTYPE_0 0x01 53 #define OPTYPE_1 0x02 54 #define OPTYPE_FF 0x03 55 //... 56 #define OPTYPE_CS 0x10 57 #define OPTYPE_DS 0x11 58 #define OPTYPE_ES 0x12 59 #define OPTYPE_FS 0x13 60 #define OPTYPE_GS 0x14 61 #define OPTYPE_SS 0x15 62 #define OPTYPE_CR0 0x16 63 #define OPTYPE_TSC 0x17 // time stamp counter 64 //... 65 #define OPTYPE_FLAGS 0x20 66 #define OPTYPE_xFLAGS 0x21 // RFLAGS/EFLAGS (depending on operand size) 67 #define OPTYPE_xCX_HI_xBX_LO 0x22 // represented by 2 registers CX:BX or ECX:EBX (depending on operand size) 68 #define OPTYPE_xDX_HI_xAX_LO 0x23 // DX:AX or EDX:EAX (depending on operand size) 69 #define OPTYPE_EDX_HI_EAX_LO 0x24 // DX:AX or EDX:EAX (depending on operand size) 70 #define OPTYPE_EDX_ECX_EBX_EAX 0x25 // all registers are set 71 //... 72 #define OPTYPE_STx 0x30 73 #define OPTYPE_ST0 0x31 74 #define OPTYPE_ST1 0x32 75 #define OPTYPE_FPU_STATUS 0x33 76 #define OPTYPE_FPU_CONTROL 0x34 77 #define OPTYPE_FPU_TAG 0x35 78 #define OPTYPE_FLDZ 0x36 // 0 79 #define OPTYPE_FLD1 0x37 // 1 80 #define OPTYPE_FLDPI 0x38 // pi 81 #define OPTYPE_FLDL2T 0x39 // lg 10 82 #define OPTYPE_FLDL2E 0x3A // lg e 83 #define OPTYPE_FLDLG2 0x3B // log_10 2 84 #define OPTYPE_FLDLN2 0x3C // log_e 2 85 //... 86 #define OPTYPE_CS_MSR 0x40 87 #define OPTYPE_EIP_MSR 0x41 88 #define OPTYPE_ESP_MSR 0x42 89 #define OPTYPE_KERNELBASE_MSR 0x43 90 #define OPTYPE_FMASK_MSR 0x44 91 #define OPTYPE_STAR_MSR 0x45 92 #define OPTYPE_CSTAR_MSR 0x46 // 32-bit mode 93 #define OPTYPE_LSTAR_MSR 0x47 // 64-bit mode 94 95 96 // NOTE: OPTYPES >= 0x80 reserved for registers (OP_REG+XX) 97 #define OPTYPE_REG_AL (OP_REG+0x01) 98 #define OPTYPE_REG_CL (OP_REG+0x02) 99 #define OPTYPE_REG_AH (OP_REG+0x03) 100 #define OPTYPE_REG_AX (OP_REG+0x04) 101 #define OPTYPE_REG_DX (OP_REG+0x05) 102 #define OPTYPE_REG_ECX (OP_REG+0x06) 103 #define OPTYPE_REG8 (OP_REG+0x07) 104 105 // If address size is 2, use BP 106 // If address size is 4, use EBP 107 // If address size is 8, use RBP 108 #define OPTYPE_REG_xBP (OP_REG+0x08) 109 110 // If address size is 2, use BP 111 // If address size is 4, use EBP 112 // If address size is 8, use RBP 113 #define OPTYPE_REG_xSP (OP_REG+0x09) 114 115 // If operand size is 2, take 8-bit register 116 // If operand size is 4, take 16-bit register 117 // If operand size is 8, take 32-bit register 118 #define OPTYPE_REG_xAX_SMALL (OP_REG+0x0a) 119 120 // If operand size is 2, take 16-bit register 121 // If operand size is 4, take 32-bit register 122 // If operand size is 8, take 64-bit register 123 #define OPTYPE_REG_xAX_BIG (OP_REG+0x0b) 124 125 typedef enum _CPU_TYPE 126 { 127 CPU_UNKNOWN=0, 128 129 /////////////////////////////////////// 130 // 1st generation 131 /////////////////////////////////////// 132 // 1978 133 //CPU_8086 = 1MB address limit, 16-bit registers 134 // 1982 135 //CPU_i186 136 137 /////////////////////////////////////// 138 // 2nd generation 139 /////////////////////////////////////// 140 // 1982 141 //CPU_I286 // 16MB limit, 16-bit registers, added protected mode 142 CPU_I287, // CPU_I286 + math coprocessor 143 144 /////////////////////////////////////// 145 // 3rd generation 146 /////////////////////////////////////// 147 // 1985 148 CPU_I386, // 32-bit registers, 4GB memory limit 149 // 1988 150 CPU_I387, // CPU_I386 + math coprocessor 151 152 /////////////////////////////////////// 153 // 4th generation (1989) 154 /////////////////////////////////////// 155 CPU_I486, 156 157 /////////////////////////////////////// 158 // 5th generation 159 /////////////////////////////////////// 160 // 1993 161 CPU_PENTIUM, // superscalar architecture 162 // 1997 163 //CPU_PENTIUM_MMX 164 165 /////////////////////////////////////// 166 // 6th generation (1995) 167 /////////////////////////////////////// 168 CPU_PENTIUM_PRO, // P6 architecture, no MMX, out-of-order execution, speculative execution 169 //CPU_CYRIX_6X86, 170 //CPU_AMD_K5 // RISC processor 171 // 1997 172 CPU_PENTIUM2, // Pentium Pro architecture + MMX 173 //CPU_AMD_K6, 174 //CPU_CYRIX_6X86MX, // Cyrix 6x86 + MMX 175 // 1998 176 CPU_AMD_K6_2, // added 3DNow! (MMX) 177 // 1999 178 // CPU_AMD_K6_3 // added SSE 179 180 /////////////////////////////////////// 181 // 7th generation 182 /////////////////////////////////////// 183 // 1999 184 CPU_PENTIUM3, // introduced SSE 185 // CPU_AMD_K7 // aka Athlon 186 // 2000 187 CPU_PENTIUM4, // introduced SSE2 and hyperthreading 188 189 // 2004? 2005? 190 CPU_PRESCOTT, // introduced SSE3 191 192 /////////////////////////////////////// 193 // 8th generation (X86-64) 194 // IA32 instruction set with 64-bit extensions, >4GB RAM 195 /////////////////////////////////////// 196 197 // 2003 198 CPU_AMD64, // includes Athlon 64 and Opteron aka X86-64 199 200 // 2004? 201 //CPU_EMD64 // Intel's version of AMD64 202 CPU_IA64 // aka Itanium: new instruction set -- adds JMPE to IA32 mode to return to IA64 native code 203 204 } CPU_TYPE; 205 206 ////////////////////////////////////////////////////////////////// 207 // Conditions (these can be OR'd) 208 ////////////////////////////////////////////////////////////////// 209 210 // Used for Flags.Preconditions 211 #define COND_O (1<<0) // overflow (signed) 212 #define COND_C (1<<1) // below (unsigned) 213 #define COND_Z (1<<2) // equal (unsigned) 214 #define COND_S (1<<3) // sign set (signed) 215 #define COND_P (1<<4) // parity even 216 #define COND_BE (1<<5) // CF or ZF is set (unsigned) 217 #define COND_L (1<<6) // (SF && !OF) || (OF && !SF) 218 #define COND_LE (1<<7) // ZF || (SF && !OF) || (OF && !SF) (signed) 219 #define COND_NO (1<<8) // !O 220 #define COND_NC (1<<9) // !C (not below, above or equal to) 221 #define COND_NZ (1<<10) // !Z (not equal) 222 #define COND_NS (1<<11) // !S 223 #define COND_NP (1<<12) // !P (parity odd) 224 #define COND_NL (1<<13) // (!SF && !OF) || (SF && OF) 225 #define COND_G (1<<14) // !ZF && ((!SF && !OF) || (SF && OF)) 226 #define COND_D (1<<15) // DF 227 #define COND_REG_xCX_BIG_Z (1<<16) // CX/ECX/RCX (depending on address size) == 0 228 #define COND_REG_xCX_BIG_NZ (1<<17) // CX/ECX/RCX (depending on address size) != 0 229 #define COND_OP1_EQ_OP2 (1<<18) 230 #define COND_OP1_EQ_OP3 (1<<19) 231 #define COND_B COND_C 232 #define COND_NAE COND_C 233 #define COND_E COND_Z 234 #define COND_NA COND_BE 235 #define COND_PE COND_P 236 #define COND_U COND_P 237 #define COND_NGE COND_L 238 #define COND_NG COND_LE 239 #define COND_PO COND_NP 240 #define COND_NU COND_NP 241 #define COND_NE COND_NZ 242 #define COND_NB COND_NC 243 #define COND_AE COND_NC 244 #define COND_NE COND_NZ 245 #define COND_A (COND_NC|COND_NZ) 246 #define COND_NBE COND_A 247 #define COND_GE COND_NL 248 #define COND_NLE COND_G 249 250 // Used for Opcode.FlagsChanged 251 #define FLAG_CF_SET (1<<0) 252 #define FLAG_DF_SET (1<<1) 253 #define FLAG_IF_SET (1<<2) 254 #define FLAG_SET_MASK (FLAG_CF_SET|FLAG_DF_SET|FLAG_IF_SET) 255 256 #define FLAG_SF_CLR (1<<3) 257 #define FLAG_ZF_CLR (1<<4) 258 #define FLAG_AF_CLR (1<<5) 259 #define FLAG_CF_CLR (1<<6) 260 #define FLAG_DF_CLR (1<<7) 261 #define FLAG_IF_CLR (1<<8) 262 #define FLAG_OF_CLR (1<<9) 263 #define FPU_C0_CLR (1<<19) 264 #define FPU_C1_CLR (1<<20) 265 #define FPU_C2_CLR (1<<21) 266 #define FPU_C3_CLR (1<<22) 267 #define FPU_ALL_CLR (FPU_C0_CLR|FPU_C1_CLR|FPU_C2_CLR|FPU_C3_CLR) 268 #define FLAG_CLR_MASK (FLAG_SF_CLR|FLAG_ZF_CLR|FLAG_AF_CLR|FLAG_CF_CLR|FLAG_DF_CLR|FLAG_IF_CLR|FLAG_OF_CLR|FPU_ALL_CLR) 269 270 #define FLAG_OF_MOD (1<<10) 271 #define FLAG_SF_MOD (1<<11) 272 #define FLAG_ZF_MOD (1<<12) 273 #define FLAG_AF_MOD (1<<13) 274 #define FLAG_PF_MOD (1<<14) 275 #define FLAG_CF_MOD (1<<15) 276 #define FLAG_DF_MOD (1<<16) 277 #define FLAG_IF_MOD (1<<17) 278 #define FLAG_ALL_MOD (FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD|FLAG_CF_MOD|FLAG_DF_MOD|FLAG_IF_MOD) 279 #define FLAG_COMMON_MOD (FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD|FLAG_CF_MOD) 280 #define FPU_C0_MOD (1<<23) 281 #define FPU_C1_MOD (1<<24) 282 #define FPU_C2_MOD (1<<25) 283 #define FPU_C3_MOD (1<<26) 284 #define FPU_ALL_MOD (FPU_C0_MOD|FPU_C1_MOD|FPU_C2_MOD|FPU_C3_MOD) 285 #define FLAG_MOD_MASK (FLAG_ALL_MOD|FPU_ALL_MOD) 286 287 #define FLAG_CF_TOG (1<<18) 288 #define FLAG_TOG_MASK FLAG_CF_TOG 289 290 // Used for Opcode.ResultsIfTrue and Opcode.ResultsIfFalse 291 #define OP1_DST (1<<0) 292 #define OP2_DST (1<<1) 293 #define OP3_DST (1<<2) 294 #define OP1_SRC (1<<3) 295 #define OP2_SRC (1<<4) 296 #define OP3_SRC (1<<5) 297 #define FPU_STACK_INC (1<<6) 298 #define FPU_STACK_INC2 (1<<7) 299 #define FPU_STACK_DEC (1<<8) 300 #define SERIALIZE_WRITE (1<<9) 301 #define SERIALIZE_READ (1<<10) 302 #define xCX_DEC (1<<11) 303 #define xCX_REP_DEC (1<<12) 304 #define xDI_DEC (1<<13) 305 #define xDI_INC (1<<14) 306 #define xSI_DEC (1<<15) 307 #define xSI_INC (1<<16) 308 #define xDI_DECx (1<<17) 309 #define xDI_INCx (1<<18) 310 #define xSI_DECx (1<<19) 311 #define xSI_INCx (1<<20) 312 #define FPU_STACK_PUSH FPU_STACK_DEC 313 #define FPU_STACK_POP FPU_STACK_INC 314 #define FPU_STACK_POP2 FPU_STACK_INC2 315 #define SERIALIZE_ALL (SERIALIZE_WRITE|SERIALIZE_READ) 316 317 #define X86_SEGMENT_OFFSET 0x00 318 #define X86_TEST_OFFSET 0x10 319 #define X86_CONTROL_OFFSET 0x20 320 #define X86_DEBUG_OFFSET 0x30 321 #define X86_FPU_OFFSET 0x40 322 #define X86_MMX_OFFSET 0x50 323 #define X86_XMM_OFFSET 0x60 324 #define X86_8BIT_OFFSET 0x70 325 #define X86_16BIT_OFFSET 0x80 326 #define X86_32BIT_OFFSET 0x90 327 #define AMD64_8BIT_OFFSET 0xA0 328 #define AMD64_16BIT_OFFSET 0xB0 329 #define AMD64_32BIT_OFFSET 0xC0 330 #define AMD64_64BIT_OFFSET 0xD0 331 332 typedef enum _X86_REGISTER 333 { 334 // Segments 335 X86_SEG_ES = X86_SEGMENT_OFFSET, 336 X86_SEG_CS, 337 X86_SEG_SS, 338 X86_SEG_DS, 339 X86_SEG_FS, 340 X86_SEG_GS, 341 342 // Miscellaneous 343 X86_REG_FLAGS, 344 X86_REG_EFLAGS, 345 AMD64_REG_RFLAGS, 346 X86_REG_IP, 347 X86_REG_EIP, 348 AMD64_REG_RIP, 349 350 // Test registers 351 X86_REG_TR0 = X86_TEST_OFFSET, 352 X86_REG_TR1, 353 X86_REG_TR2, 354 X86_REG_TR3, 355 X86_REG_TR4, 356 X86_REG_TR5, 357 X86_REG_TR6, 358 X86_REG_TR7, 359 X86_REG_TR8, 360 X86_REG_TR9, 361 X86_REG_TR10, 362 X86_REG_TR11, 363 X86_REG_TR12, 364 X86_REG_TR13, 365 X86_REG_TR14, 366 X86_REG_TR15, 367 368 // Control registers 369 X86_REG_CR0=X86_CONTROL_OFFSET, 370 X86_REG_CR1, 371 X86_REG_CR2, 372 X86_REG_CR3, 373 X86_REG_CR4, 374 X86_REG_CR5, 375 X86_REG_CR6, 376 X86_REG_CR7, 377 X86_REG_CR8, 378 X86_REG_CR9, 379 X86_REG_CR10, 380 X86_REG_CR11, 381 X86_REG_CR12, 382 X86_REG_CR13, 383 X86_REG_CR14, 384 X86_REG_CR15, 385 386 // Debug registers 387 X86_REG_DR0=X86_DEBUG_OFFSET, 388 X86_REG_DR1, 389 X86_REG_DR2, 390 X86_REG_DR3, 391 X86_REG_DR4, 392 X86_REG_DR5, 393 X86_REG_DR6, 394 X86_REG_DR7, 395 X86_REG_DR8, 396 X86_REG_DR9, 397 X86_REG_DR10, 398 X86_REG_DR11, 399 X86_REG_DR12, 400 X86_REG_DR13, 401 X86_REG_DR14, 402 X86_REG_DR15, 403 404 // FPU registers 405 X86_REG_ST0=X86_FPU_OFFSET, 406 X86_REG_ST1, 407 X86_REG_ST2, 408 X86_REG_ST3, 409 X86_REG_ST4, 410 X86_REG_ST5, 411 X86_REG_ST6, 412 X86_REG_ST7, 413 414 // MMX registers 415 X86_REG_MM0=X86_MMX_OFFSET, 416 X86_REG_MM1, 417 X86_REG_MM2, 418 X86_REG_MM3, 419 X86_REG_MM4, 420 X86_REG_MM5, 421 X86_REG_MM6, 422 X86_REG_MM7, 423 424 // XMM registers 425 X86_REG_XMM0=X86_XMM_OFFSET, 426 X86_REG_XMM1, 427 X86_REG_XMM2, 428 X86_REG_XMM3, 429 X86_REG_XMM4, 430 X86_REG_XMM5, 431 X86_REG_XMM6, 432 X86_REG_XMM7, 433 434 // 8-bit registers 435 X86_REG_AL=X86_8BIT_OFFSET, 436 X86_REG_CL, 437 X86_REG_DL, 438 X86_REG_BL, 439 X86_REG_AH, 440 X86_REG_CH, 441 X86_REG_DH, 442 X86_REG_BH, 443 444 // 16-bit registers 445 X86_REG_AX=X86_16BIT_OFFSET, 446 X86_REG_CX, 447 X86_REG_DX, 448 X86_REG_BX, 449 X86_REG_SP, 450 X86_REG_BP, 451 X86_REG_SI, 452 X86_REG_DI, 453 454 // 32-bit registers 455 X86_REG_EAX=X86_32BIT_OFFSET, 456 X86_REG_ECX, 457 X86_REG_EDX, 458 X86_REG_EBX, 459 X86_REG_ESP, 460 X86_REG_EBP, 461 X86_REG_ESI, 462 X86_REG_EDI, 463 464 // AMD64 8-bit registers 465 AMD64_REG_AL=AMD64_8BIT_OFFSET, 466 AMD64_REG_CL, 467 AMD64_REG_DL, 468 AMD64_REG_BL, 469 AMD64_REG_SPL, 470 AMD64_REG_BPL, 471 AMD64_REG_SIL, 472 AMD64_REG_DIL, 473 AMD64_REG_R8B, 474 AMD64_REG_R9B, 475 AMD64_REG_R10B, 476 AMD64_REG_R11B, 477 AMD64_REG_R12B, 478 AMD64_REG_R13B, 479 AMD64_REG_R14B, 480 AMD64_REG_R15B, 481 482 // AMD64 16-bit registers 483 AMD64_REG_AX=AMD64_16BIT_OFFSET, 484 AMD64_REG_CX, 485 AMD64_REG_DX, 486 AMD64_REG_BX, 487 AMD64_REG_SP, 488 AMD64_REG_BP, 489 AMD64_REG_SI, 490 AMD64_REG_DI, 491 AMD64_REG_R8W, 492 AMD64_REG_R9W, 493 AMD64_REG_R10W, 494 AMD64_REG_R11W, 495 AMD64_REG_R12W, 496 AMD64_REG_R13W, 497 AMD64_REG_R14W, 498 AMD64_REG_R15W, 499 500 // AMD64 32-bit registers 501 AMD64_REG_EAX=AMD64_32BIT_OFFSET, 502 AMD64_REG_ECX, 503 AMD64_REG_EDX, 504 AMD64_REG_EBX, 505 AMD64_REG_ESP, 506 AMD64_REG_EBP, 507 AMD64_REG_ESI, 508 AMD64_REG_EDI, 509 AMD64_REG_R8D, 510 AMD64_REG_R9D, 511 AMD64_REG_R10D, 512 AMD64_REG_R11D, 513 AMD64_REG_R12D, 514 AMD64_REG_R13D, 515 AMD64_REG_R14D, 516 AMD64_REG_R15D, 517 518 // AMD64 64-bit registers 519 AMD64_REG_RAX=AMD64_64BIT_OFFSET, 520 AMD64_REG_RCX, 521 AMD64_REG_RDX, 522 AMD64_REG_RBX, 523 AMD64_REG_RSP, 524 AMD64_REG_RBP, 525 AMD64_REG_RSI, 526 AMD64_REG_RDI, 527 AMD64_REG_R8, 528 AMD64_REG_R9, 529 AMD64_REG_R10, 530 AMD64_REG_R11, 531 AMD64_REG_R12, 532 AMD64_REG_R13, 533 AMD64_REG_R14, 534 AMD64_REG_R15 535 } X86_REGISTER; 536 537 typedef enum _X86_TEST_REGISTER 538 { 539 REG_TR0=0, 540 REG_TR1, 541 REG_TR2, 542 REG_TR3, 543 REG_TR4, 544 REG_TR5, 545 REG_TR6, 546 REG_TR7, 547 REG_TR8, 548 REG_TR9, 549 REG_TR10, 550 REG_TR11, 551 REG_TR12, 552 REG_TR13, 553 REG_TR14, 554 REG_TR15 555 } X86_TEST_REGISTER; 556 557 typedef enum _X86_CONTROL_REGISTER 558 { 559 REG_CR0, 560 REG_CR1, 561 REG_CR2, 562 REG_CR3, 563 REG_CR4, 564 REG_CR5, 565 REG_CR6, 566 REG_CR7, 567 REG_CR8, 568 REG_CR9, 569 REG_CR10, 570 REG_CR11, 571 REG_CR12, 572 REG_CR13, 573 REG_CR14, 574 REG_CR15 575 } X86_CONTROL_REGISTER; 576 577 typedef enum _X86_DEBUG_REGISTER 578 { 579 REG_DR0, 580 REG_DR1, 581 REG_DR2, 582 REG_DR3, 583 REG_DR4, 584 REG_DR5, 585 REG_DR6, 586 REG_DR7, 587 REG_DR8, 588 REG_DR9, 589 REG_DR10, 590 REG_DR11, 591 REG_DR12, 592 REG_DR13, 593 REG_DR14, 594 REG_DR15 595 } X86_DEBUG_REGISTER; 596 597 typedef enum _X86_MMX_REGISTER 598 { 599 REG_MM0=0, 600 REG_MM1=1, 601 REG_MM2=2, 602 REG_MM3=3, 603 REG_MM4=4, 604 REG_MM5=5, 605 REG_MM6=6, 606 REG_MM7=7 607 } X86_MMX_REGISTER; 608 609 typedef enum _X86_SSE_REGISTER 610 { 611 REG_XMM0=0, 612 REG_XMM1=1, 613 REG_XMM2=2, 614 REG_XMM3=3, 615 REG_XMM4=4, 616 REG_XMM5=5, 617 REG_XMM6=6, 618 REG_XMM7=7 619 } X86_SSE_REGISTER; 620 621 typedef enum _X86_FPU_REGISTER 622 { 623 REG_ST0=0, 624 REG_ST1=1, 625 REG_ST2=2, 626 REG_ST3=3, 627 REG_ST4=4, 628 REG_ST5=5, 629 REG_ST6=6, 630 REG_ST7=7 631 } X86_FPU_REGISTER; 632 633 typedef enum _X86_8BIT_REGISTER 634 { 635 REG_AL = 0, 636 REG_CL = 1, 637 REG_DL = 2, 638 REG_BL = 3, 639 REG_AH = 4, 640 REG_CH = 5, 641 REG_DH = 6, 642 REG_BH = 7 643 } X86_8BIT_REGISTER; 644 645 typedef enum _X86_16BIT_REGISTER 646 { 647 REG_AX = 0, 648 REG_CX = 1, 649 REG_DX = 2, 650 REG_BX = 3, 651 REG_SP = 4, 652 REG_BP = 5, 653 REG_SI = 6, 654 REG_DI = 7 655 } X86_16BIT_REGISTER; 656 657 typedef enum _X86_32BIT_REGISTER 658 { 659 REG_EAX = 0, 660 REG_ECX = 1, 661 REG_EDX = 2, 662 REG_EBX = 3, 663 REG_ESP = 4, 664 REG_EBP = 5, 665 REG_ESI = 6, 666 REG_EDI = 7 667 } X86_32BIT_REGISTER; 668 669 typedef enum _X86_SEGMENT 670 { 671 SEG_ES = 0, 672 SEG_CS = 1, 673 SEG_SS = 2, 674 SEG_DS = 3, 675 SEG_FS = 4, 676 SEG_GS = 5, 677 SEG_MAX = 6 678 } X86_SEGMENT; 679 680 extern char *X86_Registers[]; 681 682 #pragma pack(push,1) 683 typedef struct _MODRM 684 { 685 U8 mod : 2; 686 U8 reg : 3; 687 U8 rm : 3; 688 } MODRM; 689 typedef struct _SIB 690 { 691 U8 scale : 2; 692 U8 index : 3; 693 U8 base : 3; 694 } SIB; 695 typedef struct _REX 696 { 697 U8 unused : 4; // bits 4,5,6,7 698 U8 w : 1; // bit 3 699 U8 r : 1; // bit 2 700 U8 x : 1; // bit 1 701 U8 b : 1; // bit 0 702 } REX; 703 typedef struct _REX_MODRM 704 { 705 U8 reg : 4; 706 U8 rm : 4; 707 } REX_MODRM; 708 typedef struct _REX_SIB 709 { 710 U8 index : 4; 711 U8 base : 4; 712 } REX_SIB; 713 #pragma pack(pop) 714 715 // 716 // Properties: 717 // If an operand is OP_COND_EXEC, it means that it is executed only if the pre-conditions are met. 718 // 719 // If if an instruction has one or more OP_COND_DST operands, then the actions are determined by 720 // whether the Opcode.Preconditions are met or not. If all the COND_* flags in Opcode.Preconditions 721 // are true, then the results are determined by ResultsIfTrue. If the preconditions are not met, then 722 // the results are determined by ResultsIfFalse. 723 // 724 // If Preconditions == NOCOND, then results in ResultsIfTrue are unconditional and ResultsIfFalse 725 // is ignored 726 // 727 typedef struct _X86_OPCODE 728 { 729 struct _X86_OPCODE *Table; 730 CPU_TYPE CPU; // minimum CPU (starting with i386) 731 U32 MnemonicFlags; 732 char Mnemonic[X86_MAX_INSTRUCTION_LEN+1]; 733 U32 OperandFlags[X86_MAX_OPERANDS]; 734 U32 Preconditions; 735 U32 FlagsChanged; // changes in flags 736 U32 ResultsIfTrue; // results if Preconditions are met 737 U32 ResultsIfFalse; // results if Preconditions are not met 738 } X86_OPCODE; 739 740 typedef struct _X86_INSTRUCTION 741 { 742 struct _INSTRUCTION *Instruction; // the generic instruction format representing this instruction 743 744 X86_OPCODE Opcode; 745 746 U8 sib_b; 747 U8 modrm_b; 748 MODRM modrm; 749 SIB sib; 750 U8 rex_b; 751 REX rex; 752 REX_MODRM rex_modrm; 753 REX_SIB rex_sib; 754 755 X86_SEGMENT DstSegment; 756 union 757 { 758 X86_SEGMENT Segment; 759 DWORD Selector; 760 }; 761 762 // NOTE: these are for internal use, use Instruction->Operands[] 763 // 764 // If DstRegAddressing or SrcRegAddressing = TRUE then BaseRegister is the base register 765 // It is the operand represented by SIBOperand 766 // 767 // The operand indices of the destination operands is in DstOpIndex[0 to DstOpCount-1] 768 // The operand indices of the source operands is in SrcOpIndex[0 to SrcOpCount-1] 769 // 770 // These are used both for instructions like xadd/xchg (where both operands are source/destination) 771 // and to represent implicit registers (e.g., cmpxchg) 772 773 U8 SrcOpIndex[3]; 774 U8 DstOpIndex[3]; 775 776 // Addressing mode: 777 // If DstRegAddressing = TRUE, then these apply to DstReg 778 // If SrcRegAddressing = TRUE, then this applies to SrcReg[AddressIndex] 779 // If both are false, then SrcReg and DstReg are not addresses 780 X86_REGISTER BaseRegister; 781 X86_REGISTER IndexRegister; 782 783 U8 Scale; 784 U8 HasDefault64Operand : 1; 785 U8 HasOperandSizePrefix : 1; 786 U8 HasAddressSizePrefix : 1; 787 U8 HasSegmentOverridePrefix : 1; 788 U8 HasLockPrefix : 1; 789 U8 HasRepeatWhileEqualPrefix : 1; 790 U8 HasRepeatWhileNotEqualPrefix : 1; 791 U8 HasBranchTakenPrefix : 1; 792 U8 HasBranchNotTakenPrefix : 1; 793 U8 HasDstAddressing : 1; 794 U8 HasSrcAddressing : 1; 795 U8 HasModRM : 1; 796 U8 HasBaseRegister : 1; 797 U8 HasIndexRegister : 1; 798 U8 HasFullDisplacement : 1; 799 U8 HasDstSegment : 1; // used for ins/cmps/scas/movs/etc which have 2 segments 800 U8 DstAddressIndex : 2; // DstOpIndex[DstAddressIndex] 801 U8 SrcAddressIndex : 2; // SrcOpIndex[SrcAddressIndex] 802 U8 DstOpCount : 2; 803 U8 SrcOpCount : 2; 804 U8 OperandSize : 4; 805 U8 AddressSize : 4; 806 U8 Relative : 1; 807 U8 HasSelector : 1; // segment is actually a selector 808 U8 Group : 5; 809 810 S64 Displacement; 811 812 } X86_INSTRUCTION; 813 814 //////////////////////////////////////////////////////////////////////////////////// 815 // Exported functions 816 //////////////////////////////////////////////////////////////////////////////////// 817 818 extern ARCHITECTURE_FORMAT_FUNCTIONS X86; 819 820 // Instruction setup 821 BOOL X86_InitInstruction(struct _INSTRUCTION *Instruction); 822 void X86_CloseInstruction(struct _INSTRUCTION *Instruction); 823 824 // Instruction translator 825 BOOL X86_TranslateInstruction(struct _INSTRUCTION *Instruction, BOOL Verbose); 826 827 // Instruction decoder 828 BOOL X86_GetInstruction(struct _INSTRUCTION *Instruction, U8 *Address, DWORD Flags); 829 830 // Function finding 831 U8 *X86_FindFunctionByPrologue(struct _INSTRUCTION *Instruction, U8 *StartAddress, U8 *EndAddress, DWORD Flags); 832 833 #ifdef __cplusplus 834 } 835 #endif 836 #endif // X86_DISASM_H 837 838