x86dis.c (37184B)
1 // X86 assembly library, adapted for use in VX32 2 3 #include "x86dis.h" 4 #include <string.h> 5 #include <stdio.h> 6 7 #define offsetof(S, x) (int)(&((S*)0)->x) 8 #define nelem(x) (sizeof(x)/sizeof((x)[0])) 9 10 typedef unsigned int uint; 11 12 enum 13 { 14 O_AAA = 1, 15 O_AAD, 16 O_AAM, 17 O_AAS, 18 O_ADC, 19 O_ADD, 20 O_ADDRSIZE, 21 O_AND, 22 O_ARPL, 23 O_BOUND, 24 O_BSF, 25 O_BSR, 26 O_BT, 27 O_BTC, 28 O_BTR, 29 O_BTS, 30 O_CBW, 31 O_CLC, 32 O_CLD, 33 O_CLI, 34 O_CLTS, 35 O_CMC, 36 O_CMP, 37 O_CMPS, 38 O_CMPXCHG, 39 O_CPUID, 40 O_CWD, 41 O_DAA, 42 O_DAS, 43 O_DATASIZE, 44 O_DEC, 45 O_DIV, 46 O_ENTER, 47 O_HALT, 48 O_IDIV, 49 O_IMUL, 50 O_IMUL2, 51 O_IMUL3, 52 O_IN, 53 O_INC, 54 O_INS, 55 O_INT, 56 O_IRET, 57 O_JA, 58 O_JC, 59 O_JCXZ, 60 O_JG, 61 O_JGE, 62 O_JL, 63 O_JLE, 64 O_JMP, 65 O_JMPF, 66 O_JNA, 67 O_JNC, 68 O_JNO, 69 O_JNP, 70 O_JNS, 71 O_JNZ, 72 O_JO, 73 O_JP, 74 O_JS, 75 O_JZ, 76 O_LAHF, 77 O_LAR, 78 O_LDS, 79 O_LEA, 80 O_LEAVE, 81 O_LES, 82 O_LFS, 83 O_LGDT, 84 O_LGS, 85 O_LIDT, 86 O_LLDT, 87 O_LMSW, 88 O_LOCK, 89 O_LODS, 90 O_LOOP, 91 O_LOOPNZ, 92 O_LOOPZ, 93 O_LSL, 94 O_LSS, 95 O_LTR, 96 O_MODRM, 97 O_MOV, 98 O_MOVS, 99 O_MOVSXB, 100 O_MOVSXW, 101 O_MOVZB, 102 O_MOVZW, 103 O_MUL, 104 O_NEG, 105 O_NEXTB, 106 O_NOP, 107 O_NOT, 108 O_OR, 109 O_OUT, 110 O_OUTS, 111 O_POP, 112 O_POPA, 113 O_POPF, 114 O_PUSH, 115 O_PUSHA, 116 O_PUSHF, 117 O_RCL, 118 O_RCR, 119 O_REP, 120 O_REPNE, 121 O_RET, 122 O_RETF, 123 O_ROL, 124 O_ROR, 125 O_SAHF, 126 O_SAR, 127 O_SBB, 128 O_SCAS, 129 O_SEGMENT, 130 O_SETA, 131 O_SETC, 132 O_SETG, 133 O_SETGE, 134 O_SETL, 135 O_SETLE, 136 O_SETNA, 137 O_SETNC, 138 O_SETNO, 139 O_SETNP, 140 O_SETNS, 141 O_SETNZ, 142 O_SETO, 143 O_SETP, 144 O_SETS, 145 O_SETZ, 146 O_SGDT, 147 O_SHL, 148 O_SHLD, 149 O_SHR, 150 O_SHRD, 151 O_SIDT, 152 O_SLDT, 153 O_SMSW, 154 O_STC, 155 O_STD, 156 O_STI, 157 O_STOS, 158 O_STR, 159 O_SUB, 160 O_TEST, 161 O_VERR, 162 O_VERW, 163 O_WAIT, 164 O_XCHG, 165 O_XOR, 166 O_CALL, 167 O_CALLF, 168 O_XLAT, 169 170 MAXO 171 }; 172 173 enum 174 { 175 F_8 = 1, 176 F_16, 177 F_32, 178 F_1632, 179 F_0A, 180 F_X, 181 }; 182 183 enum 184 { 185 A_0 = 5, 186 A_1 = 1, 187 A_3 = 3, 188 A_4 = 4, 189 190 A_AL = 8, 191 A_CL, 192 A_DL, 193 A_BL, 194 A_AH, 195 A_CH, 196 A_DH, 197 A_BH, 198 199 A_AX, 200 A_CX, 201 A_DX, 202 A_BX, 203 A_SP, 204 A_BP, 205 A_SI, 206 A_DI, 207 208 A_EAX, 209 A_ECX, 210 A_EDX, 211 A_EBX, 212 A_ESP, 213 A_EBP, 214 A_ESI, 215 A_EDI, 216 217 A_ES, 218 A_CS, 219 A_SS, 220 A_DS, 221 A_FS, 222 A_GS, 223 224 A_IMM8, 225 A_IMM16, 226 A_IMM32, 227 228 A_CR, 229 A_DR, 230 A_TR, 231 A_SR, 232 233 A_M, 234 235 A_MOFF8, 236 A_MOFF16, 237 A_MOFF32, 238 239 A_R8, 240 A_R16, 241 A_R32, 242 243 A_RM8, 244 A_RM16, 245 A_RM32, 246 A_RM32R, 247 248 A_REL8, 249 A_REL16, 250 A_REL32, 251 A_IMM1616, 252 A_IMM1632, 253 254 MAXA 255 }; 256 257 enum 258 { 259 D_LOCK = 1<<0, 260 D_REP = 1<<1, 261 D_REPN = 1<<2, 262 D_ES = 1<<3, 263 D_CS = 1<<4, 264 D_SS = 1<<5, 265 D_DS = 1<<6, 266 D_FS = 1<<7, 267 D_GS = 1<<8, 268 D_ADDR32 = 1<<9, 269 D_DATA8 = 1<<10, 270 D_DATA16 = 1<<11, 271 D_DATA32 = 1<<12, 272 D_STACK32 = 1<<13, 273 }; 274 275 enum 276 { 277 DA_NONE, 278 DA_REG8, 279 DA_REG16, 280 DA_REG32, 281 DA_IMM, 282 DA_MEM, 283 DA_SEGMEM, 284 DA_IND16, 285 DA_IND32, 286 DA_SIB, 287 DA_SIBX, 288 DA_SEG16, 289 DA_REL, 290 }; 291 292 // String tables 293 294 static char *opnames[MAXO][3] = 295 { 296 { "xxx" }, 297 [O_AAA] { "aaa" }, 298 [O_AAD] { "aad" }, 299 [O_AAM] { "aam" }, 300 [O_AAS] { "aas" }, 301 [O_ADC] { "adcb", "adcw", "adcl" }, 302 [O_ADD] { "addb", "addw", "addl" }, 303 [O_ADDRSIZE] { "addrsize" }, 304 [O_AND] { "andb", "andw", "andl" }, 305 [O_ARPL] { "arpl" }, 306 [O_BOUND] { 0, "boundw", "boundl" }, 307 [O_BSF] { 0, "bsfw", "bsfl" }, 308 [O_BSR] { 0, "bsrw", "bsrl" }, 309 [O_BT] { 0, "btw", "btl" }, 310 [O_BTC] { 0, "btcw", "btcl" }, 311 [O_BTR] { 0, "btrw", "btrl" }, 312 [O_BTS] { 0, "btsw", "btsl" }, 313 [O_CALL] { 0, "call", "call" }, 314 [O_CBW] { 0, "cbw", "cwde" }, 315 [O_CLC] { "clc" }, 316 [O_CLD] { "cld" }, 317 [O_CLI] { "cli" }, 318 [O_CLTS] { "clts" }, 319 [O_CMC] { "cmc" }, 320 [O_CMP] { "cmpb", "cmpw", "cmpl" }, 321 [O_CMPS] { "cmpsb", "cmpsw", "cmpsl" }, 322 [O_CMPXCHG] { "cmpxchgb", "cmpxchgw", "cmpxchgl" }, 323 [O_CPUID] { "cpuid" }, 324 [O_CWD] { 0, "cwd", "cdq" }, 325 [O_DAA] { "daa" }, 326 [O_DAS] { "das" }, 327 [O_DATASIZE] { "datasize" }, 328 [O_DEC] { "decb", "decw", "decl" }, 329 [O_DIV] { "divb", "divw", "divl" }, 330 [O_ENTER] { "enter" }, 331 [O_HALT] { "halt" }, 332 [O_IDIV] { "idivb", "idivw", "idivl" }, 333 [O_IMUL] { "imulb", "imulw", "imull" }, 334 [O_IMUL2] { "imulb", "imulw", "imull" }, 335 [O_IMUL3] { "imulb", "imulw", "imull" }, 336 [O_IN] { "inb", "inw", "inl" }, 337 [O_INC] { "incb", "incw", "incl" }, 338 [O_INS] { "insb", "insw", "insl" }, 339 [O_INT] { "int" }, 340 [O_IRET] { 0, "iret", "iretd" }, 341 [O_JA] { "ja", "ja", "ja" }, 342 [O_JC] { "jc", "jc", "jc" }, 343 [O_JCXZ] { "jcxz", "jcxz", "jcxz" }, 344 [O_JG] { "jg", "jg", "jg" }, 345 [O_JGE] { "jge", "jge", "jge" }, 346 [O_JL] { "jl", "jl", "jl" }, 347 [O_JLE] { "jle", "jle", "jle" }, 348 [O_JMP] { "jmp", "jmp", "jmp" }, 349 [O_JMPF] { "ljmp", "ljmp", "ljmp" }, 350 [O_JNA] { "jna", "jna", "jna" }, 351 [O_JNC] { "jnc", "jnc", "jnc" }, 352 [O_JNO] { "jno", "jno", "jno" }, 353 [O_JNP] { "jnp", "jnp", "jnp" }, 354 [O_JNS] { "jns", "jns", "jns" }, 355 [O_JNZ] { "jnz", "jnz", "jnz" }, 356 [O_JO] { "jo", "jo", "jo" }, 357 [O_JP] { "jp", "jp", "jp" }, 358 [O_JS] { "js", "js", "js" }, 359 [O_JZ] { "jz", "jz", "jz" }, 360 [O_LAHF] { "lahf" }, 361 [O_LAR] { 0, "larw", "larl" }, 362 [O_LEA] { 0, "leaw", "leal" }, 363 [O_LEAVE] { 0, "leavew", "leavel" }, 364 [O_LGDT] { "lgdt", }, 365 [O_LDS] { 0, "ldsw", "ldsl" }, 366 [O_LES] { 0, "lesw", "lesl" }, 367 [O_LFS] { 0, "lfsw", "lfsl" }, 368 [O_LGS] { 0, "lgsw", "lgsl" }, 369 [O_LSS] { 0, "lssw", "lssl" }, 370 [O_LIDT] { "lidt" }, 371 [O_LLDT] { "lldt" }, 372 [O_LMSW] { 0, "lmsw" }, 373 [O_LOCK] { "*LOCK*" }, 374 [O_LODS] { "lodsb", "lodsw", "lodsl" }, 375 [O_LOOP] { "loop" }, 376 [O_LOOPNZ] { "loopnz" }, 377 [O_LOOPZ] { "loopz" }, 378 [O_LSL] { 0, "lslw", "lsll" }, 379 [O_LTR] { 0, "ltr", 0 }, 380 [O_MODRM] { "*MODRM*" }, 381 [O_MOV] { "movb", "movw", "movl" }, 382 [O_MOVS] { "movsb", "movsw", "movsl" }, 383 [O_MOVSXB] { 0, "movsxb", "movsxb" }, 384 [O_MOVSXW] { 0, 0, "movsxw" }, 385 [O_MOVZB] { 0, "movzb", "movzb" }, 386 [O_MOVZW] { 0, 0, "movzw" }, 387 [O_MUL] { "mulb", "mulw", "mull" }, 388 [O_NEG] { "negb", "negw", "negl" }, 389 [O_NEXTB] { "*NEXTB*" }, 390 [O_NOP] { "nop" }, 391 [O_NOT] { "notb", "notw", "notl" }, 392 [O_OR] { "orb", "orw", "orl" }, 393 [O_OUT] { "outb", "outw", "outl" }, 394 [O_OUTS] { "outsb", "outsw", "outsl" }, 395 [O_POP] { 0, "popw", "popl" }, 396 [O_POPA] { 0, "popaw", "popal" }, 397 [O_POPF] { 0, "popfw", "popfl" }, 398 [O_PUSH] { 0, "pushw", "pushl" }, 399 [O_PUSHA] { 0, "pushaw", "pushal" }, 400 [O_PUSHF] { 0, "pushfw", "pushfl" }, 401 [O_RCL] { "rclb", "rclw", "rcll" }, 402 [O_RCR] { "rcrb", "rcrw", "rcrl" }, 403 [O_REP] { "rep" }, 404 [O_REPNE] { "repne" }, 405 [O_RET] { "ret", "ret", "ret" }, 406 [O_RETF] { "retf", "retf", "retf" }, 407 [O_ROL] { "rolb", "rolw", "roll" }, 408 [O_ROR] { "rorb", "rorw", "rorl" }, 409 [O_SAHF] { "sahf" }, 410 [O_SAR] { "sarb", "sarw", "sarl" }, 411 [O_SBB] { "sbbb", "sbbw", "sbbl" }, 412 [O_SCAS] { "scasb", "scasw", "scasl" }, 413 [O_SEGMENT] { "*SEGMENT*" }, 414 [O_SETA] { "seta" }, 415 [O_SETC] { "setc" }, 416 [O_SETG] { "setg" }, 417 [O_SETGE] { "setge" }, 418 [O_SETL] { "setl" }, 419 [O_SETLE] { "setle" }, 420 [O_SETNA] { "setna" }, 421 [O_SETNC] { "setnc" }, 422 [O_SETNO] { "setno" }, 423 [O_SETNP] { "setnp" }, 424 [O_SETNS] { "setns" }, 425 [O_SETNZ] { "setnz" }, 426 [O_SETO] { "seto" }, 427 [O_SETP] { "setp" }, 428 [O_SETS] { "sets" }, 429 [O_SETZ] { "setz" }, 430 [O_SGDT] { "sgdt" }, 431 [O_SHL] { "shlb", "shlw", "shll" }, 432 [O_SHLD] { 0, "shldw", "shldl" }, 433 [O_SHR] { "shrb", "shrw", "shrl" }, 434 [O_SHRD] { 0, "shrdw", "shrdl" }, 435 [O_SIDT] { "sidt" }, 436 [O_SLDT] { "sldt" }, 437 [O_SMSW] { 0, "smsw" }, 438 [O_STC] { "stc" }, 439 [O_STD] { "std" }, 440 [O_STI] { "sti" }, 441 [O_STOS] { "stosb", "stosw", "stosl" }, 442 [O_STR] { 0, "str" }, 443 [O_SUB] { "subb", "subw", "subl" }, 444 [O_TEST] { "testb", "testw", "testl" }, 445 [O_VERR] { 0, "verr" }, 446 [O_VERW] { 0, "verw" }, 447 [O_WAIT] { "wait" }, 448 [O_XCHG] { "xchgb", "xchgw", "xchgl" }, 449 [O_XOR] { "xorb", "xorw", "xorl" }, 450 [O_XLAT] { "xlat" }, 451 }; 452 453 static struct { 454 int f; 455 char *s; 456 } prefixes[] = { 457 D_LOCK, "lock", 458 D_REP, "rep", 459 D_REPN, "repn", 460 D_CS, "cs:", 461 D_DS, "ds:", 462 D_ES, "es:", 463 D_FS, "fs:", 464 D_GS, "gs:", 465 D_SS, "ss:", 466 }; 467 468 static char *reg8[] = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" }; 469 static char *reg16[] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" }; 470 static char *reg32[] = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", 471 "eip", "eflags", 472 "cr0", "cr2", "cr3", 473 "dr0", "dr1", "dr2", "dr3", "dr6", "dr7", 474 "tr6", "tr7" }; 475 static char *seg[] = { "cs", "ds", "es", "fs", "gs", "ss" }; 476 477 // Register Ids 478 479 #define EAX 0 480 #define ECX 4 481 #define EDX 8 482 #define EBX 12 483 #define ESP 16 484 #define EBP 20 485 #define ESI 24 486 #define EDI 28 487 #define EIP 32 488 #define EFLAGS 36 489 #define CR0 40 490 #define CR2 44 491 #define CR3 48 492 #define DR0 52 493 #define DR1 56 494 #define DR2 60 495 #define DR3 64 496 #define DR6 68 497 #define DR7 72 498 #define TR6 76 499 #define TR7 80 500 501 #define CS 100 502 #define DS 101 503 #define ES 102 504 #define FS 103 505 #define GS 104 506 #define SS 105 507 // Instruction decoding tables. 508 509 static xinst inst0F00[] = 510 { 511 /*/0*/ { O_SLDT, F_16, A_RM16, }, 512 { O_STR, F_16, A_RM16, }, 513 { O_LLDT, F_16, A_RM16, }, 514 { O_LTR, F_16, A_RM16, }, 515 { O_VERR, F_16, A_RM16, }, 516 { O_VERW, F_16, A_RM16, }, 517 { -1 }, 518 { -1 }, 519 }; 520 521 static xinst inst0F01[] = 522 { 523 { O_SGDT, F_X, A_M, }, 524 { O_SIDT, F_X, A_M, }, 525 { O_LGDT, F_X, A_M, }, 526 { O_LIDT, F_X, A_M, }, 527 { O_SMSW, F_16, A_RM16, }, 528 { -1 }, 529 { O_LMSW, F_16, A_RM16, }, 530 { -1 }, 531 }; 532 533 static xinst inst0FBA[] = 534 { 535 { -1 }, 536 { -1 }, 537 { -1 }, 538 { -1 }, 539 { O_BT, F_1632, A_RM16, A_IMM8 }, 540 { O_BTS, F_1632, A_RM16, A_IMM8 }, 541 { O_BTR, F_1632, A_RM16, A_IMM8 }, 542 { O_BTC, F_1632, A_RM16, A_IMM8 }, 543 }; 544 545 static xinst inst0F[] = 546 { 547 /*00*/ { O_MODRM, 0, 0, 0, 0, inst0F00 }, 548 { O_MODRM, 0, 0, 0, 0, inst0F01 }, 549 { O_LAR, F_1632, A_R16, A_RM16, }, 550 { O_LSL, F_1632, A_R16, A_RM16, }, 551 { -1 }, 552 { -1 }, 553 { O_CLTS, F_X, 0, 0, }, 554 { -1 }, 555 /*08*/ { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, 556 /*10*/ { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, 557 /*18*/ { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, 558 /*20*/ { O_MOV, F_32, A_RM32R, A_CR }, 559 { O_MOV, F_32, A_RM32R, A_DR }, 560 { O_MOV, F_32, A_CR, A_RM32R }, 561 { O_MOV, F_32, A_DR, A_RM32R }, 562 { O_MOV, F_32, A_RM32R, A_TR }, 563 { -1 }, 564 { O_MOV, F_32, A_TR, A_RM32R }, 565 { -1 }, 566 /*28*/ { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, 567 /*30*/ { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, 568 /*38*/ { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, 569 /*40*/ { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, 570 /*48*/ { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, 571 /*50*/ { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, 572 /*58*/ { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, 573 /*60*/ { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, 574 /*68*/ { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, 575 /*70*/ { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, 576 /*78*/ { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, 577 /*80*/ { O_JO, F_1632, A_REL16, }, 578 { O_JNO, F_1632, A_REL16, }, 579 { O_JC, F_1632, A_REL16, }, 580 { O_JNC, F_1632, A_REL16, }, 581 { O_JZ, F_1632, A_REL16, }, 582 { O_JNZ, F_1632, A_REL16, }, 583 { O_JNA, F_1632, A_REL16, }, 584 { O_JA, F_1632, A_REL16, }, 585 /*88*/ { O_JS, F_1632, A_REL16, }, 586 { O_JNS, F_1632, A_REL16, }, 587 { O_JP, F_1632, A_REL16, }, 588 { O_JNP, F_1632, A_REL16, }, 589 { O_JL, F_1632, A_REL16, }, 590 { O_JGE, F_1632, A_REL16, }, 591 { O_JLE, F_1632, A_REL16, }, 592 { O_JG, F_1632, A_REL16, }, 593 /*90*/ { O_SETO, F_8, A_RM8, }, 594 { O_SETNO, F_8, A_RM8, }, 595 { O_SETC, F_8, A_RM8, }, 596 { O_SETNC, F_8, A_RM8, }, 597 { O_SETZ, F_8, A_RM8, }, 598 { O_SETNZ, F_8, A_RM8, }, 599 { O_SETNA, F_8, A_RM8, }, 600 { O_SETA, F_8, A_RM8, }, 601 /*98*/ { O_SETS, F_8, A_RM8, }, 602 { O_SETNS, F_8, A_RM8, }, 603 { O_SETP, F_8, A_RM8, }, 604 { O_SETNP, F_8, A_RM8, }, 605 { O_SETL, F_8, A_RM8, }, 606 { O_SETGE, F_8, A_RM8, }, 607 { O_SETLE, F_8, A_RM8, }, 608 { O_SETG, F_8, A_RM8, }, 609 /*A0*/ { O_PUSH, 0, A_FS, }, 610 { O_POP, 0, A_FS, }, 611 { O_CPUID, F_X, 0, 0 }, 612 { O_BT, F_1632, A_RM16, A_R16 }, 613 { O_SHLD, F_1632, A_RM16, A_R16, A_IMM8 }, 614 { O_SHLD, F_1632, A_RM16, A_R16, A_CL }, 615 { -1 }, 616 { -1 }, 617 /*A8*/ { O_PUSH, 0, A_GS, }, 618 { O_POP, 0, A_GS, }, 619 { -1 }, 620 { O_BTS, F_1632, A_RM16, A_R16 }, 621 { O_SHRD, F_1632, A_RM16, A_R16, A_IMM8 }, 622 { O_SHRD, F_1632, A_RM16, A_R16, A_CL }, 623 { -1 }, 624 { O_IMUL2, F_1632, A_R16, A_RM16 }, 625 /*B0*/ { O_CMPXCHG, F_8, A_AL, A_RM8, A_R8 }, 626 { O_CMPXCHG, F_1632, A_AX, A_RM16, A_R16 }, 627 { O_LSS, F_1632, A_R16, A_M }, 628 { O_BTR, F_1632, A_RM16, A_R16 }, 629 { O_LFS, F_1632, A_R16, A_M }, 630 { O_LGS, F_1632, A_R16, A_M }, 631 { O_MOVZB, F_1632, A_R16, A_RM8 }, 632 { O_MOVZW, F_32, A_R32, A_RM16 }, 633 /*B8*/ { -1 }, 634 { -1 }, 635 { O_MODRM, 0, 0, 0, 0, inst0FBA }, 636 { O_BTC, F_1632, A_RM16, A_R16 }, 637 { O_BSF, F_1632, A_R16, A_RM16 }, 638 { O_BSR, F_1632, A_R16, A_RM16 }, 639 { O_MOVSXB, F_1632, A_R16, A_RM8 }, 640 { O_MOVSXW, F_32, A_R32, A_RM16 }, 641 /*C0*/ { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, 642 /*C8*/ { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, 643 /*D0*/ { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, 644 /*D8*/ { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, 645 /*E0*/ { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, 646 /*E8*/ { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, 647 /*F0*/ { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, 648 /*F8*/ { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, 649 }; 650 651 static xinst inst80[] = 652 { 653 { O_ADD, F_8, A_RM8, A_IMM8 }, 654 { O_OR, F_8, A_RM8, A_IMM8 }, 655 { O_ADC, F_8, A_RM8, A_IMM8 }, 656 { O_SBB, F_8, A_RM8, A_IMM8 }, 657 { O_AND, F_8, A_RM8, A_IMM8 }, 658 { O_SUB, F_8, A_RM8, A_IMM8 }, 659 { O_XOR, F_8, A_RM8, A_IMM8 }, 660 { O_CMP, F_8, A_RM8, A_IMM8 }, 661 }; 662 663 static xinst inst81[] = 664 { 665 { O_ADD, F_1632, A_RM16, A_IMM16 }, 666 { O_OR, F_1632, A_RM16, A_IMM16 }, 667 { O_ADC, F_1632, A_RM16, A_IMM16 }, 668 { O_SBB, F_1632, A_RM16, A_IMM16 }, 669 { O_AND, F_1632, A_RM16, A_IMM16 }, 670 { O_SUB, F_1632, A_RM16, A_IMM16 }, 671 { O_XOR, F_1632, A_RM16, A_IMM16 }, 672 { O_CMP, F_1632, A_RM16, A_IMM16 }, 673 }; 674 675 static xinst inst83[] = 676 { 677 { O_ADD, F_1632, A_RM16, A_IMM8 }, 678 { O_OR, F_1632, A_RM16, A_IMM8 }, 679 { O_ADC, F_1632, A_RM16, A_IMM8 }, 680 { O_SBB, F_1632, A_RM16, A_IMM8 }, 681 { O_AND, F_1632, A_RM16, A_IMM8 }, 682 { O_SUB, F_1632, A_RM16, A_IMM8 }, 683 { O_XOR, F_1632, A_RM16, A_IMM8 }, 684 { O_CMP, F_1632, A_RM16, A_IMM8 }, 685 }; 686 687 static xinst inst8F[] = 688 { 689 { O_POP, F_1632, A_M, 0, }, 690 { -1 }, 691 { -1 }, 692 { -1 }, 693 { -1 }, 694 { -1 }, 695 { -1 }, 696 { -1 }, 697 }; 698 699 static xinst instC0[] = 700 { 701 { O_ROL, F_8, A_RM8, A_IMM8, }, 702 { O_ROR, F_8, A_RM8, A_IMM8, }, 703 { O_RCL, F_8, A_RM8, A_IMM8, }, 704 { O_RCR, F_8, A_RM8, A_IMM8, }, 705 { O_SHL, F_8, A_RM8, A_IMM8, }, 706 { O_SHR, F_8, A_RM8, A_IMM8, }, 707 { -1, }, 708 { O_SAR, F_8, A_RM8, A_IMM8, }, 709 }; 710 711 static xinst instC1[] = 712 { 713 { O_ROL, F_1632, A_RM16, A_IMM8, }, 714 { O_ROR, F_1632, A_RM16, A_IMM8, }, 715 { O_RCL, F_1632, A_RM16, A_IMM8, }, 716 { O_RCR, F_1632, A_RM16, A_IMM8, }, 717 { O_SHL, F_1632, A_RM16, A_IMM8, }, 718 { O_SHR, F_1632, A_RM16, A_IMM8, }, 719 { -1, }, 720 { O_SAR, F_1632, A_RM16, A_IMM8, }, 721 }; 722 723 static xinst instD0[] = 724 { 725 { O_ROL, F_8, A_RM8, A_1, }, 726 { O_ROR, F_8, A_RM8, A_1, }, 727 { O_RCL, F_8, A_RM8, A_1, }, 728 { O_RCR, F_8, A_RM8, A_1, }, 729 { O_SHL, F_8, A_RM8, A_1, }, 730 { O_SHR, F_8, A_RM8, A_1, }, 731 { -1, }, 732 { O_SAR, F_8, A_RM8, A_1, }, 733 }; 734 735 static xinst instD1[] = 736 { 737 { O_ROL, F_1632, A_RM16, A_1, }, 738 { O_ROR, F_1632, A_RM16, A_1, }, 739 { O_RCL, F_1632, A_RM16, A_1, }, 740 { O_RCR, F_1632, A_RM16, A_1, }, 741 { O_SHL, F_1632, A_RM16, A_1, }, 742 { O_SHR, F_1632, A_RM16, A_1, }, 743 { -1, }, 744 { O_SAR, F_1632, A_RM16, A_1, }, 745 }; 746 747 static xinst instD2[] = 748 { 749 { O_ROL, F_8, A_RM8, A_CL, }, 750 { O_ROR, F_8, A_RM8, A_CL, }, 751 { O_RCL, F_8, A_RM8, A_CL, }, 752 { O_RCR, F_8, A_RM8, A_CL, }, 753 { O_SHL, F_8, A_RM8, A_CL, }, 754 { O_SHR, F_8, A_RM8, A_CL, }, 755 { -1, }, 756 { O_SAR, F_8, A_RM8, A_CL, }, 757 }; 758 759 static xinst instD3[] = 760 { 761 { O_ROL, F_1632, A_RM16, A_CL, }, 762 { O_ROR, F_1632, A_RM16, A_CL, }, 763 { O_RCL, F_1632, A_RM16, A_CL, }, 764 { O_RCR, F_1632, A_RM16, A_CL, }, 765 { O_SHL, F_1632, A_RM16, A_CL, }, 766 { O_SHR, F_1632, A_RM16, A_CL, }, 767 { -1, }, 768 { O_SAR, F_1632, A_RM16, A_CL, }, 769 }; 770 771 static xinst instF6[] = 772 { 773 { O_TEST, F_8, A_RM8, A_IMM8, }, 774 { -1 }, 775 { O_NOT, F_8, A_RM8, 0, }, 776 { O_NEG, F_8, A_RM8, 0, }, 777 { O_MUL, F_8, A_AL, A_RM8, }, 778 { O_IMUL, F_8, A_RM8, }, 779 { O_DIV, F_8, A_AX, A_RM8, }, 780 { O_IDIV, F_8, A_AX, A_RM8, }, 781 }; 782 static xinst instF7[] = 783 { 784 { O_TEST, F_1632, A_RM16, A_IMM16, }, 785 { -1 }, 786 { O_NOT, F_1632, A_RM16, 0, }, 787 { O_NEG, F_1632, A_RM16, 0, }, 788 { O_MUL, F_1632, A_AX, A_RM16, }, 789 { O_IMUL, F_1632, A_RM16, }, 790 { O_DIV, F_1632, A_RM16, }, 791 { O_IDIV, F_1632, A_RM16, }, 792 }; 793 794 static xinst instFE[] = 795 { 796 { O_INC, F_8, A_RM8, 0, }, 797 { O_DEC, F_8, A_RM8, 0, }, 798 { -1 }, 799 { -1 }, 800 { -1 }, 801 { -1 }, 802 { -1 }, 803 { -1 }, 804 { -1 }, 805 { -1 }, 806 }; 807 808 static xinst instFF[] = 809 { 810 { O_INC, F_1632, A_RM16, 0, }, 811 { O_DEC, F_1632, A_RM16, 0, }, 812 { O_CALL, F_1632, A_RM16, 0, }, 813 { O_CALLF, F_1632, A_M, 0, }, // INDIRECT 814 { O_JMP, F_1632, A_RM16, 0, }, 815 { O_JMPF, F_1632, A_M, 0, }, // INDIRECT 816 { O_PUSH, F_1632, A_M, 0, }, 817 { -1 }, 818 }; 819 820 xinst inst[] = 821 { 822 /*00*/ { O_ADD, F_8, A_RM8, A_R8 }, 823 { O_ADD, F_1632, A_RM16, A_R16 }, 824 { O_ADD, F_8, A_R8, A_RM8 }, 825 { O_ADD, F_1632, A_R16, A_RM16 }, 826 { O_ADD, F_8, A_AL, A_IMM8 }, 827 { O_ADD, F_1632, A_AX, A_IMM16 }, 828 { O_PUSH, 0, A_ES, }, 829 { O_POP, 0, A_ES, }, 830 /*08*/ { O_OR, F_8, A_RM8, A_R8 }, 831 { O_OR, F_1632, A_RM16, A_R16 }, 832 { O_OR, F_8, A_R8, A_RM8 }, 833 { O_OR, F_1632, A_R16, A_RM16 }, 834 { O_OR, F_8, A_AL, A_IMM8 }, 835 { O_OR, F_1632, A_AX, A_IMM16 }, 836 { O_PUSH, 0, A_CS, }, 837 { O_NEXTB, 0, 0, 0, 0, inst0F }, 838 /*10*/ { O_ADC, F_8, A_RM8, A_R8 }, 839 { O_ADC, F_1632, A_RM16, A_R16 }, 840 { O_ADC, F_8, A_R8, A_RM8 }, 841 { O_ADC, F_1632, A_R16, A_RM16 }, 842 { O_ADC, F_8, A_AL, A_IMM8 }, 843 { O_ADC, F_1632, A_AX, A_IMM16 }, 844 { O_PUSH, 0, A_SS, }, 845 { O_POP, 0, A_SS, }, 846 /*18*/ { O_SBB, F_8, A_RM8, A_R8 }, 847 { O_SBB, F_1632, A_RM16, A_R16 }, 848 { O_SBB, F_8, A_R8, A_RM8 }, 849 { O_SBB, F_1632, A_R16, A_RM16 }, 850 { O_SBB, F_8, A_AL, A_IMM8 }, 851 { O_SBB, F_1632, A_AX, A_IMM16 }, 852 { O_PUSH, F_1632, A_DS, 0, }, 853 { O_POP, F_1632, A_DS, 0, }, 854 /*20*/ { O_AND, F_8, A_RM8, A_R8 }, 855 { O_AND, F_1632, A_RM16, A_R16 }, 856 { O_AND, F_8, A_R8, A_RM8 }, 857 { O_AND, F_1632, A_R16, A_RM16 }, 858 { O_AND, F_8, A_AL, A_IMM8 }, 859 { O_AND, F_1632, A_AX, A_IMM16 }, 860 { O_SEGMENT, 0, A_ES, 0, }, 861 { O_DAA, F_X, 0, 0, }, 862 /*28*/ { O_SUB, F_8, A_RM8, A_R8 }, 863 { O_SUB, F_1632, A_RM16, A_R16 }, 864 { O_SUB, F_8, A_R8, A_RM8 }, 865 { O_SUB, F_1632, A_R16, A_RM16 }, 866 { O_SUB, F_8, A_AL, A_IMM8 }, 867 { O_SUB, F_1632, A_AX, A_IMM16 }, 868 { O_SEGMENT, 0, A_CS, 0, }, 869 { O_DAS, F_X, 0, 0, }, 870 /*30*/ { O_XOR, F_8, A_RM8, A_R8 }, 871 { O_XOR, F_1632, A_RM16, A_R16 }, 872 { O_XOR, F_8, A_R8, A_RM8 }, 873 { O_XOR, F_1632, A_R16, A_RM16 }, 874 { O_XOR, F_8, A_AL, A_IMM8 }, 875 { O_XOR, F_1632, A_AX, A_IMM16 }, 876 { O_SEGMENT, 0, A_SS, 0, }, 877 { O_AAA, F_X, 0, 0, }, 878 /*38*/ { O_CMP, F_8, A_RM8, A_R8 }, 879 { O_CMP, F_1632, A_RM16, A_R16 }, 880 { O_CMP, F_8, A_R8, A_RM8 }, 881 { O_CMP, F_1632, A_R16, A_RM16 }, 882 { O_CMP, F_8, A_AL, A_IMM8 }, 883 { O_CMP, F_1632, A_AX, A_IMM16 }, 884 { O_SEGMENT, 0, A_DS, 0, }, 885 { O_AAS, F_X, 0, 0, }, 886 /*40*/ { O_INC, F_1632, A_AX, 0, }, // +r 887 { O_INC, F_1632, A_CX, 0, }, 888 { O_INC, F_1632, A_DX, 0, }, 889 { O_INC, F_1632, A_BX, 0, }, 890 { O_INC, F_1632, A_SP, 0, }, 891 { O_INC, F_1632, A_BP, 0, }, 892 { O_INC, F_1632, A_SI, 0, }, 893 { O_INC, F_1632, A_DI, 0, }, 894 /*48*/ { O_DEC, F_1632, A_AX, 0, }, // +r 895 { O_DEC, F_1632, A_CX, 0, }, 896 { O_DEC, F_1632, A_DX, 0, }, 897 { O_DEC, F_1632, A_BX, 0, }, 898 { O_DEC, F_1632, A_SP, 0, }, 899 { O_DEC, F_1632, A_BP, 0, }, 900 { O_DEC, F_1632, A_SI, 0, }, 901 { O_DEC, F_1632, A_DI, 0, }, 902 /*50*/ { O_PUSH, F_1632, A_AX, 0, }, // +r 903 { O_PUSH, F_1632, A_CX, 0, }, 904 { O_PUSH, F_1632, A_DX, 0, }, 905 { O_PUSH, F_1632, A_BX, 0, }, 906 { O_PUSH, F_1632, A_SP, 0, }, 907 { O_PUSH, F_1632, A_BP, 0, }, 908 { O_PUSH, F_1632, A_SI, 0, }, 909 { O_PUSH, F_1632, A_DI, 0, }, 910 /*58*/ { O_POP, F_1632, A_AX, 0, }, // +r 911 { O_POP, F_1632, A_CX, 0, }, 912 { O_POP, F_1632, A_DX, 0, }, 913 { O_POP, F_1632, A_BX, 0, }, 914 { O_POP, F_1632, A_SP, 0, }, 915 { O_POP, F_1632, A_BP, 0, }, 916 { O_POP, F_1632, A_SI, 0, }, 917 { O_POP, F_1632, A_DI, 0, }, 918 /*60*/ { O_PUSHA, F_1632, 0, 0, }, 919 { O_POPA, F_1632, 0, 0, }, 920 { O_BOUND, F_1632, A_R16, A_M, }, 921 { O_ARPL, F_X, A_RM16, A_R16, }, 922 { O_SEGMENT, 0, A_FS, 0, }, 923 { O_SEGMENT, 0, A_GS, 0, }, 924 { O_DATASIZE, 0, 0, 0, }, 925 { O_ADDRSIZE, 0, 0, 0, }, 926 /*68*/ { O_PUSH, F_1632, A_IMM16, 0, }, 927 { O_IMUL3, F_1632, A_R16, A_RM16, A_IMM16 }, 928 { O_PUSH, F_1632, A_IMM8, 0, }, 929 { O_IMUL3, F_1632, A_R16, A_RM16, A_IMM8 }, 930 { O_INS, F_8, 0, 0 }, 931 { O_INS, F_1632, 0, 0, }, 932 { O_OUTS, F_8, 0, 0, }, 933 { O_OUTS, F_1632, 0, 0, }, 934 /*70*/ { O_JO, F_8, A_REL8, }, 935 { O_JNO, F_8, A_REL8, }, 936 { O_JC, F_8, A_REL8, }, 937 { O_JNC, F_8, A_REL8, }, 938 { O_JZ, F_8, A_REL8, }, 939 { O_JNZ, F_8, A_REL8, }, 940 { O_JNA, F_8, A_REL8, }, 941 { O_JA, F_8, A_REL8, }, 942 /*78*/ { O_JS, F_8, A_REL8, }, 943 { O_JNS, F_8, A_REL8, }, 944 { O_JP, F_8, A_REL8, }, 945 { O_JNP, F_8, A_REL8, }, 946 { O_JL, F_8, A_REL8, }, 947 { O_JGE, F_8, A_REL8, }, 948 { O_JLE, F_8, A_REL8, }, 949 { O_JG, F_8, A_REL8, }, 950 /*80*/ { O_MODRM, 0, 0, 0, 0, inst80 }, 951 { O_MODRM, 0, 0, 0, 0, inst81 }, 952 { -1 }, 953 { O_MODRM, 0, 0, 0, 0, inst83 }, 954 { O_TEST, F_8, A_RM8, A_R8, }, 955 { O_TEST, F_1632, A_RM16, A_R16, }, 956 { O_XCHG, F_8, A_R8, A_RM8, }, 957 { O_XCHG, F_1632, A_R16, A_RM16, }, 958 /*88*/ { O_MOV, F_8, A_RM8, A_R8, }, 959 { O_MOV, F_1632, A_RM16, A_R16, }, 960 { O_MOV, F_8, A_R8, A_RM8, }, 961 { O_MOV, F_1632, A_R16, A_RM16, }, 962 { O_MOV, F_16, A_RM16, A_SR }, 963 { O_LEA, F_1632, A_R16, A_M }, 964 { O_MOV, F_16, A_SR, A_RM16 }, 965 { O_MODRM, 0, 0, 0, 0, inst8F }, 966 /*90*/ { O_NOP, F_X, 0, 0, }, // really XCHG +r 967 { O_XCHG, F_1632, A_CX, A_R16 }, 968 { O_XCHG, F_1632, A_DX, A_R16 }, 969 { O_XCHG, F_1632, A_BX, A_R16 }, 970 { O_XCHG, F_1632, A_SP, A_R16 }, 971 { O_XCHG, F_1632, A_BP, A_R16 }, 972 { O_XCHG, F_1632, A_SI, A_R16 }, 973 { O_XCHG, F_1632, A_DI, A_R16 }, 974 /*98*/ { O_CBW, F_1632, 0, 0 }, // or CWDE 975 { O_CWD, F_1632, 0, 0, }, // or CDQ 976 { O_CALLF, F_1632, A_IMM1616, 0, }, 977 { O_WAIT, F_X, 0, 0, }, 978 { O_PUSHF, F_1632, 0, 0, }, 979 { O_POPF, F_1632, 0, 0, }, 980 { O_SAHF, F_X, 0, 0, }, 981 { O_LAHF, F_X, 0, 0, }, 982 /*A0*/ { O_MOV, F_8, A_AL, A_MOFF8 }, 983 { O_MOV, F_1632, A_AX, A_MOFF16}, 984 { O_MOV, F_8, A_MOFF8,A_AL }, 985 { O_MOV, F_1632, A_MOFF16, A_AX}, 986 { O_MOVS, F_8, 0, 0 }, 987 { O_MOVS, F_1632, 0, 0, }, 988 { O_CMPS, F_8, 0, 0 }, 989 { O_CMPS, F_1632, 0, 0, }, 990 /*A8*/ { O_TEST, F_8, A_AL, A_IMM8 }, 991 { O_TEST, F_1632, A_AX, A_IMM16 }, 992 { O_STOS, F_8, 0, 0 }, 993 { O_STOS, F_1632, 0, 0, }, 994 { O_LODS, F_8, 0, 0 }, 995 { O_LODS, F_1632, 0, 0, }, 996 { O_SCAS, F_8, 0, 0 }, 997 { O_SCAS, F_1632, 0, 0, }, 998 /*B0*/ { O_MOV, F_8, A_AL, A_IMM8, }, // +r 999 { O_MOV, F_8, A_CL, A_IMM8, }, 1000 { O_MOV, F_8, A_DL, A_IMM8, }, 1001 { O_MOV, F_8, A_BL, A_IMM8, }, 1002 { O_MOV, F_8, A_AH, A_IMM8, }, 1003 { O_MOV, F_8, A_CH, A_IMM8, }, 1004 { O_MOV, F_8, A_DH, A_IMM8, }, 1005 { O_MOV, F_8, A_BH, A_IMM8, }, 1006 /*B8*/ { O_MOV, F_1632, A_AX, A_IMM16, }, // +r 1007 { O_MOV, F_1632, A_CX, A_IMM16, }, 1008 { O_MOV, F_1632, A_DX, A_IMM16, }, 1009 { O_MOV, F_1632, A_BX, A_IMM16, }, 1010 { O_MOV, F_1632, A_SP, A_IMM16, }, 1011 { O_MOV, F_1632, A_BP, A_IMM16, }, 1012 { O_MOV, F_1632, A_SI, A_IMM16, }, 1013 { O_MOV, F_1632, A_DI, A_IMM16, }, 1014 /*C0*/ { O_MODRM, 0, 0, 0, 0, instC0 }, 1015 { O_MODRM, 0, 0, 0, 0, instC1 }, 1016 { O_RET, 0, A_IMM16, 0, }, 1017 { O_RET, 0, 0, 0, }, 1018 { O_LES, F_1632, A_R16, A_M }, 1019 { O_LDS, F_1632, A_R16, A_M }, 1020 { O_MOV, F_8, A_RM8, A_IMM8 }, 1021 { O_MOV, F_1632, A_RM16, A_IMM16 }, 1022 /*C8*/ { O_ENTER, 0, A_IMM16, A_IMM8 }, 1023 { O_LEAVE, F_1632, 0, 0, }, 1024 { O_RETF, 0, A_IMM16, 0, }, 1025 { O_RETF, 0, 0, 0, }, 1026 { O_INT, F_X, A_3, 0, }, 1027 { O_INT, F_X, A_IMM8, 0, }, 1028 { O_INT, F_X, A_4, 0, }, 1029 { O_IRET, F_1632, 0, 0, }, 1030 /*D0*/ { O_MODRM, 0, 0, 0, 0, instD0 }, 1031 { O_MODRM, 0, 0, 0, 0, instD1 }, 1032 { O_MODRM, 0, 0, 0, 0, instD2 }, 1033 { O_MODRM, 0, 0, 0, 0, instD3 }, 1034 { O_AAM, F_0A, 0, 0, }, 1035 { O_AAD, F_0A, 0, 0, }, 1036 { -1 }, 1037 { O_XLAT, F_8 }, 1038 /*D8*/ { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, 1039 /*E0*/ { O_LOOPNZ, F_8, A_REL8, 0, }, 1040 { O_LOOPZ, F_8, A_REL8, 0, }, 1041 { O_LOOP, F_8, A_REL8, 0, }, 1042 { O_JCXZ, F_8, A_REL8, 0, }, 1043 { O_IN, F_8, A_AL, A_IMM8, }, 1044 { O_IN, F_1632, A_AX, A_IMM8, }, 1045 { O_OUT, F_8, A_IMM8, A_AL, }, 1046 { O_OUT, F_1632, A_IMM8, A_AX, }, 1047 /*E8*/ { O_CALL, F_1632, A_REL16, 0, }, 1048 { O_JMP, F_1632, A_REL16, 0, }, 1049 { O_JMPF, F_1632, A_IMM1616, 0, }, 1050 { O_JMP, F_8, A_REL8, 0, }, 1051 { O_IN, F_8, A_AL, A_DX, }, 1052 { O_IN, F_1632, A_AX, A_DX, }, // DX not part of 16 -> 32 1053 { O_OUT, F_8, A_DX, A_AL, }, 1054 { O_OUT, F_1632, A_DX, A_AX, }, 1055 /*F0*/ { O_LOCK, 0, 0, 0, }, 1056 { -1 }, 1057 { O_REPNE, 0, 0, 0, }, 1058 { O_REP, 0, 0, 0, }, // or O_REPE depending on next inst 1059 { O_HALT, F_X, 0, 0, }, 1060 { O_CMC, F_X, 0, 0, }, 1061 { O_MODRM, 0, 0, 0, 0, instF6 }, 1062 { O_MODRM, 0, 0, 0, 0, instF7 }, 1063 /*F8*/ { O_CLC, F_X, 0, 0, }, 1064 { O_STC, F_X, 0, 0, }, 1065 { O_CLI, F_X, 0, 0, }, 1066 { O_STI, F_X, 0, 0, }, 1067 { O_CLD, F_X, 0, 0, }, 1068 { O_STD, F_X, 0, 0, }, 1069 { O_MODRM, 0, 0, 0, 0, instFE }, 1070 { O_MODRM, 0, 0, 0, 0, instFF }, 1071 }; 1072 1073 // Argument decoding tables. 1074 1075 static int needsmodrm[MAXA] = 1076 { 1077 [A_CR] 1, 1078 [A_DR] 1, 1079 [A_TR] 1, 1080 [A_SR] 1, 1081 1082 [A_R8] 1, 1083 [A_R16] 1, 1084 [A_R32] 1, 1085 1086 [A_M] 1, 1087 1088 [A_RM8] 1, 1089 [A_RM16] 1, 1090 [A_RM32] 1, 1091 }; 1092 1093 static int cvt32[MAXA] = 1094 { 1095 [A_AX] A_EAX, 1096 [A_CX] A_ECX, 1097 [A_DX] A_EDX, 1098 [A_BX] A_EBX, 1099 [A_SP] A_ESP, 1100 [A_BP] A_EBP, 1101 [A_SI] A_ESI, 1102 [A_DI] A_EDI, 1103 [A_IMM16] A_IMM32, 1104 [A_R16] A_R32, 1105 [A_RM16] A_RM32, 1106 [A_REL16] A_REL32, 1107 [A_IMM1616] A_IMM1632, 1108 }; 1109 1110 static int acvt32[MAXA] = 1111 { 1112 [A_MOFF16] A_MOFF32, 1113 }; 1114 1115 1116 // Addressing mode tables. 1117 1118 static xdarg daimm = { DA_IMM }; 1119 static xdarg darel = { DA_REL }; 1120 1121 static xdarg daseg[] = { 1122 { DA_SEG16, ES }, 1123 { DA_SEG16, CS }, 1124 { DA_SEG16, SS }, 1125 { DA_SEG16, DS }, 1126 { DA_SEG16, FS }, 1127 { DA_SEG16, GS }, 1128 }; 1129 1130 #define L 0 // offset of al in eax 1131 #define H 1 // offset of ah in eax 1132 #define X 0 // offset of ax in eax 1133 1134 static xdarg dareg[] = { 1135 { DA_REG8, EAX+L }, 1136 { DA_REG8, ECX+L }, 1137 { DA_REG8, EDX+L }, 1138 { DA_REG8, EBX+L }, 1139 { DA_REG8, EAX+H }, 1140 { DA_REG8, ECX+H }, 1141 { DA_REG8, EDX+H }, 1142 { DA_REG8, EBX+H }, 1143 1144 { DA_REG16, EAX+X }, 1145 { DA_REG16, ECX+X }, 1146 { DA_REG16, EDX+X }, 1147 { DA_REG16, EBX+X }, 1148 { DA_REG16, ESP+X }, 1149 { DA_REG16, EBP+X }, 1150 { DA_REG16, ESI+X }, 1151 { DA_REG16, EDI+X }, 1152 1153 { DA_REG32, EAX }, 1154 { DA_REG32, ECX }, 1155 { DA_REG32, EDX }, 1156 { DA_REG32, EBX }, 1157 { DA_REG32, ESP }, 1158 { DA_REG32, EBP }, 1159 { DA_REG32, ESI }, 1160 { DA_REG32, EDI }, 1161 }; 1162 1163 static xdarg dacr[] = { 1164 { DA_REG32, CR0 }, 1165 { DA_NONE }, 1166 { DA_REG32, CR2 }, 1167 { DA_REG32, CR3 }, 1168 { DA_NONE }, 1169 { DA_NONE }, 1170 { DA_NONE }, 1171 { DA_NONE }, 1172 }; 1173 1174 static xdarg dadr[] = { 1175 { DA_REG32, DR0 }, 1176 { DA_REG32, DR1 }, 1177 { DA_REG32, DR2 }, 1178 { DA_REG32, DR3 }, 1179 { DA_NONE }, 1180 { DA_NONE }, 1181 { DA_REG32, DR6 }, 1182 { DA_REG32, DR7 }, 1183 }; 1184 1185 static xdarg datr[] = { 1186 { DA_NONE }, 1187 { DA_NONE }, 1188 { DA_NONE }, 1189 { DA_NONE }, 1190 { DA_NONE }, 1191 { DA_NONE }, 1192 { DA_REG32, TR6 }, 1193 { DA_REG32, TR7 }, 1194 }; 1195 1196 static xdarg daind16[] = { 1197 { DA_IND16, EBX+X, ESI+X, 1, -DS }, 1198 { DA_IND16, EBX+X, EDI+X, 1, -DS }, 1199 { DA_IND16, EBP+X, ESI+X, 1, -SS }, 1200 { DA_IND16, EBP+X, EDI+X, 1, -SS }, 1201 { DA_IND16, ESI+X, 0, 0, -DS }, 1202 { DA_IND16, EDI+X, 0, 0, -DS }, 1203 { DA_IND16, EBP+X, 0, 0, -SS }, 1204 { DA_IND16, EBX+X, 0, 0, -DS }, 1205 1206 { DA_IND16, EBX+X, ESI+X, 1, -DS }, 1207 { DA_IND16, EBX+X, EDI+X, 1, -DS }, 1208 { DA_IND16, EBP+X, ESI+X, 1, -SS }, 1209 { DA_IND16, EBP+X, EDI+X, 1, -DS }, 1210 { DA_IND16, ESI+X, 0, 0, -DS }, 1211 { DA_IND16, EDI+X, 0, 0, -DS }, 1212 { DA_IND16, EBP+X, 0, 0, -SS }, 1213 { DA_IND16, EBX+X, 0, 0, -DS }, 1214 1215 { DA_IND16, EBX+X, ESI+X, 1, -DS }, 1216 { DA_IND16, EBX+X, EDI+X, 1, -DS }, 1217 { DA_IND16, EBP+X, ESI+X, 1, -SS }, 1218 { DA_IND16, EBP+X, EDI+X, 1, -DS }, 1219 { DA_IND16, ESI+X, 0, 0, -DS }, 1220 { DA_IND16, EDI+X, 0, 0, -DS }, 1221 { DA_IND16, EBP+X, 0, 0, -SS }, 1222 { DA_IND16, EBX+X, 0, 0, -DS }, 1223 }; 1224 1225 static xdarg daind32[] = { 1226 { DA_IND32, EAX, 0, 0, -DS }, 1227 { DA_IND32, ECX, 0, 0, -DS }, 1228 { DA_IND32, EDX, 0, 0, -DS }, 1229 { DA_IND32, EBX, 0, 0, -DS }, 1230 { DA_NONE }, 1231 { DA_IND32, EBP, 0, 0, -SS }, 1232 { DA_IND32, ESI, 0, 0, -DS }, 1233 { DA_IND32, EDI, 0, 0, -DS }, 1234 1235 { DA_IND32, EAX, 0, 0, -DS }, 1236 { DA_IND32, ECX, 0, 0, -DS }, 1237 { DA_IND32, EDX, 0, 0, -DS }, 1238 { DA_IND32, EBX, 0, 0, -DS }, 1239 { DA_NONE }, 1240 { DA_IND32, EBP, 0, 0, -SS }, 1241 { DA_IND32, ESI, 0, 0, -DS }, 1242 { DA_IND32, EDI, 0, 0, -DS }, 1243 1244 { DA_IND32, EAX, 0, 0, -DS }, 1245 { DA_IND32, ECX, 0, 0, -DS }, 1246 { DA_IND32, EDX, 0, 0, -DS }, 1247 { DA_IND32, EBX, 0, 0, -DS }, 1248 { DA_NONE }, 1249 { DA_IND32, EBP, 0, 0, -SS }, 1250 { DA_IND32, ESI, 0, 0, -DS }, 1251 { DA_IND32, EDI, 0, 0, -DS }, 1252 }; 1253 1254 static xdarg dasib[] = { 1255 { DA_SIB, 0, 0, 0, -DS }, 1256 { DA_SIB, 0, 0, 0, -DS }, 1257 { DA_SIB, 0, 0, 0, -DS }, 1258 }; 1259 1260 static xdarg dasibx[] = { 1261 { DA_SIBX, 0, 0, 0, -DS }, 1262 { DA_SIBX, 0, 0, 0, -DS }, 1263 { DA_SIBX, 0, 0, 0, -DS }, 1264 }; 1265 1266 static xdarg damem[] = { 1267 { DA_MEM, 0, 0, 0, -DS }, 1268 { DA_MEM, 0, 0, 0, -DS }, 1269 { DA_MEM, 0, 0, 0, -DS }, 1270 }; 1271 1272 static xdarg dasegmem[] = { 1273 { DA_SEGMEM }, 1274 { DA_SEGMEM }, 1275 { DA_SEGMEM }, 1276 }; 1277 1278 // Instruction decode. 1279 1280 static uint 1281 getimm8(uint8_t **pa) 1282 { 1283 return *(int8_t*)(*pa)++; 1284 } 1285 1286 static uint 1287 getimm16(uint8_t **pa) 1288 { 1289 uint8_t *a; 1290 1291 a = *pa; 1292 *pa += 2; 1293 return *(int16_t*)a; 1294 } 1295 1296 static uint 1297 getimm32(uint8_t **pa) 1298 { 1299 uint8_t *a; 1300 1301 a = *pa; 1302 *pa += 4; 1303 return *(int32_t*)a; 1304 } 1305 1306 static uint8_t* 1307 decodemodrm(uint8_t *a, uint flags, int sz, uint *reg, xdarg *ea) 1308 { 1309 int modrm, sib, s, i, b; 1310 1311 memset(ea, 0, sizeof *ea); 1312 1313 modrm = *a++; 1314 *reg = (modrm >> 3) & 7; 1315 if((modrm>>6) == 3){ 1316 *ea = dareg[8*sz + (modrm&7)]; 1317 return a; 1318 } 1319 if(!(flags&D_ADDR32)){ 1320 if((modrm>>6) == 0 && (modrm&7) == 6){ 1321 *ea = damem[sz]; 1322 ea->disp = (uint16_t)getimm16(&a); 1323 return a; 1324 } 1325 *ea = daind16[sz*8 + (modrm&7)]; 1326 switch(modrm>>6){ 1327 case 1: 1328 ea->disp = getimm8(&a); 1329 break; 1330 case 2: 1331 ea->disp = (uint16_t)getimm16(&a); 1332 break; 1333 } 1334 }else{ 1335 if((modrm>>6) == 0 && (modrm&7) == 5){ 1336 *ea = damem[sz]; 1337 ea->disp = getimm32(&a); 1338 return a; 1339 } 1340 switch(modrm&7){ 1341 default: 1342 *ea = daind32[sz*8 + (modrm&7)]; 1343 break; 1344 case 4: 1345 sib = *a++; 1346 s = (sib>>6); 1347 i = (sib>>3)&7; 1348 b = sib&7; 1349 *ea = dasib[sz]; 1350 if((modrm>>6) == 0 && b == 5){ 1351 *ea = dasibx[sz]; 1352 ea->disp = getimm32(&a); 1353 }else{ 1354 *ea = dasib[sz]; 1355 ea->reg = 4*b; 1356 } 1357 if(ea->reg == 4*4 || ea->reg == 4*5) 1358 ea->seg = -SS; 1359 if(i != 4){ 1360 ea->scale = 1<<s; 1361 ea->index = 4*i; 1362 } 1363 break; 1364 } 1365 switch(modrm>>6){ 1366 case 1: 1367 ea->disp = getimm8(&a); 1368 break; 1369 case 2: 1370 ea->disp = getimm32(&a); 1371 break; 1372 } 1373 } 1374 return a; 1375 } 1376 1377 uint8_t* 1378 x86decode(uint8_t *addr0, uint8_t *a, xdinst *dec) 1379 { 1380 int i, arg, sz, didmodrm; 1381 uint reg; 1382 xdarg ea; 1383 xinst *ip; 1384 xdarg *da; 1385 uint8_t *astart; 1386 int flags; 1387 1388 flags = D_DATA32|D_ADDR32; 1389 reg = 0; 1390 1391 astart = a; 1392 dec->addr = a - addr0; 1393 1394 ip = &inst[*a++]; 1395 1396 // xinstruction prefix. 1397 switch(ip->op){ 1398 case O_LOCK: 1399 flags |= D_LOCK; 1400 goto next; 1401 case O_REPNE: 1402 flags |= D_REPN; 1403 goto next; 1404 case O_REP: 1405 flags |= D_REP; 1406 next: 1407 ip = &inst[*a++]; 1408 break; 1409 } 1410 1411 // Address size prefix. 1412 switch(ip->op){ 1413 case O_ADDRSIZE: 1414 flags ^= D_ADDR32; 1415 ip = &inst[*a++]; 1416 break; 1417 } 1418 1419 // Operand size prefix. 1420 switch(ip->op){ 1421 case O_DATASIZE: 1422 flags ^= D_DATA16|D_DATA32; 1423 ip = &inst[*a++]; 1424 break; 1425 } 1426 1427 // Segment override. 1428 switch(ip->op){ 1429 case O_SEGMENT: 1430 flags |= D_ES << (ip->arg1 - A_ES); 1431 ip = &inst[*a++]; 1432 break; 1433 } 1434 1435 if(ip->op == O_NEXTB) 1436 ip = &ip->sub[*a++]; 1437 1438 didmodrm = 0; 1439 if(ip->op == O_MODRM){ 1440 ip = &ip->sub[(*a>>3)&7]; 1441 didmodrm = 1; 1442 } 1443 1444 switch(ip->op){ 1445 case O_ADDRSIZE: 1446 case O_DATASIZE: 1447 case O_SEGMENT: 1448 case O_LOCK: 1449 case O_REPNE: 1450 case O_REP: 1451 case -1: 1452 return NULL; 1453 } 1454 1455 switch(ip->flags){ 1456 case F_X: // Don't care about operand size; pretend 8-bit for tables. 1457 case F_8: // Force 8-bit operands 1458 flags &= ~(D_DATA16|D_DATA32); 1459 flags |= D_DATA8; 1460 break; 1461 case F_16: // Force 16-bit operands 1462 flags &= ~D_DATA32; 1463 flags |= D_DATA16; 1464 break; 1465 case F_32: // Force 32-bit operands 1466 flags &= ~D_DATA16; 1467 flags |= D_DATA32; 1468 case F_1632: // Convert 16-bit operands to 32-bit if needed 1469 break; 1470 case F_0A: // Eat 0x0A byte. 1471 if(*a++ != 0x0A) 1472 return NULL; 1473 break; 1474 } 1475 if(flags&D_DATA8) 1476 sz = 0; 1477 else if(flags&D_DATA16) 1478 sz = 1; 1479 else 1480 sz = 2; 1481 1482 if(ip->op < 0 || ip->op >= MAXO) 1483 return NULL; 1484 1485 dec->name = opnames[ip->op][sz]; 1486 1487 // Mod R/M byte if needed. 1488 if(didmodrm || needsmodrm[ip->arg1] || needsmodrm[ip->arg2]) 1489 a = decodemodrm(a, flags, sz, ®, &ea); 1490 1491 // TO DO: Use override prefixes. 1492 1493 for(i=0; i<3; i++){ 1494 arg = (&ip->arg1)[i]; 1495 da = &dec->arg[i]; 1496 if(arg == 0){ 1497 da->op = DA_NONE; 1498 continue; 1499 } 1500 if((flags&D_DATA32) && ip->flags == F_1632 && cvt32[arg]) 1501 arg = cvt32[arg]; 1502 if((flags&D_ADDR32) && acvt32[arg]) 1503 arg = acvt32[arg]; 1504 1505 switch(arg){ 1506 case A_0: 1507 *da = daimm; 1508 da->disp = 0; 1509 break; 1510 case A_1: 1511 case A_3: 1512 case A_4: 1513 *da = daimm; 1514 da->disp = arg; 1515 break; 1516 case A_AL: 1517 case A_CL: 1518 case A_DL: 1519 case A_BL: 1520 case A_AH: 1521 case A_CH: 1522 case A_DH: 1523 case A_BH: 1524 *da = dareg[arg - A_AL]; 1525 break; 1526 case A_AX: 1527 case A_CX: 1528 case A_DX: 1529 case A_BX: 1530 case A_SP: 1531 case A_BP: 1532 case A_SI: 1533 case A_DI: 1534 *da = dareg[8 + arg - A_AX]; 1535 break; 1536 case A_EAX: 1537 case A_ECX: 1538 case A_EDX: 1539 case A_EBX: 1540 case A_ESP: 1541 case A_EBP: 1542 case A_ESI: 1543 case A_EDI: 1544 *da = dareg[16 + arg - A_EAX]; 1545 break; 1546 case A_ES: 1547 case A_CS: 1548 case A_SS: 1549 case A_DS: 1550 case A_FS: 1551 case A_GS: 1552 *da = daseg[arg - A_ES]; 1553 break; 1554 1555 case A_IMM8: 1556 *da = daimm; 1557 da->disp = getimm8(&a); 1558 break; 1559 case A_IMM16: 1560 *da = daimm; 1561 da->disp = getimm16(&a); 1562 break; 1563 case A_IMM32: 1564 *da = daimm; 1565 da->disp = getimm32(&a); 1566 break; 1567 1568 case A_REL8: 1569 *da = darel; 1570 da->disp = getimm8(&a); 1571 break; 1572 case A_REL16: 1573 *da = darel; 1574 da->disp = getimm16(&a); 1575 break; 1576 case A_REL32: 1577 *da = darel; 1578 da->disp = getimm32(&a); 1579 break; 1580 1581 case A_R8: 1582 case A_R16: 1583 case A_R32: 1584 *da = dareg[sz*8 + reg]; 1585 break; 1586 1587 case A_RM8: 1588 case A_RM16: 1589 case A_RM32: 1590 *da = ea; 1591 break; 1592 1593 case A_RM32R: // A_RM32 but needs to be register 1594 *da = ea; 1595 if(da->op > DA_REG32) 1596 return NULL; 1597 break; 1598 1599 case A_M: // A_RM but needs to be memory 1600 *da = ea; 1601 if(da->op <= DA_REG32) 1602 return NULL; 1603 break; 1604 1605 case A_MOFF8: 1606 *da = damem[sz]; 1607 da->disp = getimm8(&a); 1608 break; 1609 case A_MOFF16: 1610 *da = damem[sz]; 1611 da->disp = getimm16(&a); 1612 break; 1613 case A_MOFF32: 1614 *da = damem[sz]; 1615 da->disp = getimm32(&a); 1616 break; 1617 1618 case A_SR: 1619 if(reg > 5) 1620 return NULL; 1621 *da = daseg[reg]; 1622 break; 1623 1624 case A_CR: 1625 *da = dacr[reg]; 1626 if(da->op == DA_NONE) 1627 return NULL; 1628 break; 1629 case A_DR: 1630 *da = dadr[reg]; 1631 if(da->op == DA_NONE) 1632 return NULL; 1633 break; 1634 case A_TR: 1635 *da = dadr[reg]; 1636 if(da->op == DA_NONE) 1637 return NULL; 1638 break; 1639 1640 case A_IMM1616: 1641 case A_IMM1632: 1642 *da = dasegmem[sz]; 1643 if(arg == A_IMM1616) 1644 da->disp = getimm16(&a); 1645 else 1646 da->disp = getimm32(&a); 1647 da->seg = getimm16(&a); 1648 break; 1649 1650 } 1651 } 1652 dec->opsz = 8<<sz; 1653 dec->flags = flags; 1654 dec->len = a - astart; 1655 if(dec->name == NULL) 1656 dec->name = "???"; 1657 return a; 1658 } 1659 1660 1661 // Instruction printing 1662 1663 static char* 1664 fmtseg(char *p, char *ep, xdarg *da) 1665 { 1666 if(da->seg < 0) 1667 p += snprintf(p, ep-p, "%s:", seg[-da->seg-CS]); 1668 else 1669 p += snprintf(p, ep-p, "%#x:", da->seg); 1670 return p; 1671 } 1672 1673 extern void vxrun_gentrap(void); 1674 extern void vxrun_lookup_backpatch(void); 1675 extern void vxrun_lookup_indirect(void); 1676 1677 static char* 1678 fmtarg(char *p, char *ep, xdarg *da, uint32_t npc) 1679 { 1680 uint32_t addr; 1681 1682 switch(da->op){ 1683 default: 1684 p += snprintf(p, ep-p, "a%d", da->op); 1685 break; 1686 case DA_REG8: 1687 p += snprintf(p, ep-p, "%s", reg8[da->reg/4 + 4*(da->reg%2)]); 1688 break; 1689 case DA_REG16: 1690 p += snprintf(p, ep-p, "%s", reg16[da->reg/4]); 1691 break; 1692 case DA_REG32: 1693 p += snprintf(p, ep-p, "%s", reg32[da->reg/4]); 1694 break; 1695 case DA_SEG16: 1696 p += snprintf(p, ep-p, "%s", seg[da->reg-CS]); 1697 break; 1698 case DA_IMM: 1699 p += snprintf(p, ep-p, "$%#x", da->disp); 1700 break; 1701 case DA_REL: 1702 addr = da->disp + npc; 1703 if (addr == (uint32_t)(uintptr_t)vxrun_gentrap) 1704 p += snprintf(p, ep-p, "vxrun_gentrap"); 1705 else if (addr == (uint32_t)(uintptr_t)vxrun_lookup_backpatch) 1706 p += snprintf(p, ep-p, "vxrun_lookup_backpatch"); 1707 else if (addr == (uint32_t)(uintptr_t)vxrun_lookup_indirect) 1708 p += snprintf(p, ep-p, "vxrun_lookup_indirect"); 1709 else 1710 p += snprintf(p, ep-p, "%#x", da->disp + npc); 1711 break; 1712 case DA_MEM: 1713 p = fmtseg(p, ep, da); 1714 p += snprintf(p, ep-p, "%#x", da->disp); 1715 break; 1716 case DA_SEGMEM: 1717 p += snprintf(p, ep-p, "%#x:%#x", da->seg, da->disp); 1718 break; 1719 case DA_IND16: 1720 p = fmtseg(p, ep, da); 1721 if(da->disp) 1722 p += snprintf(p, ep-p, "%#x", da->disp); 1723 p += snprintf(p, ep-p, "("); 1724 p += snprintf(p, ep-p, "%s", reg16[da->reg/4]); 1725 if(da->scale) 1726 p += snprintf(p, ep-p, "+%s", reg16[da->reg/4]); 1727 p += snprintf(p, ep-p, ")"); 1728 break; 1729 case DA_IND32: 1730 p = fmtseg(p, ep, da); 1731 if(da->disp) 1732 p += snprintf(p, ep-p, "%#x", da->disp); 1733 p += snprintf(p, ep-p, "(%s)", reg32[da->reg/4]); 1734 break; 1735 case DA_SIB: 1736 case DA_SIBX: 1737 p = fmtseg(p, ep, da); 1738 if(da->disp) 1739 p += snprintf(p, ep-p, "%#x", da->disp); 1740 p += snprintf(p, ep-p, "("); 1741 if(da->op != DA_SIBX) 1742 p += snprintf(p, ep-p, "%s+", reg32[da->reg/4]); 1743 if(da->scale > 1) 1744 p += snprintf(p, ep-p, "%d*", da->scale); 1745 p += snprintf(p, ep-p, "%s", reg32[da->index/4]); 1746 p += snprintf(p, ep-p, ")"); 1747 break; 1748 } 1749 return p; 1750 } 1751 1752 int 1753 x86print(char *buf, int nbuf, xdinst *dec) 1754 { 1755 int i; 1756 char *p, *ep; 1757 1758 p = buf; 1759 ep = buf + nbuf; 1760 for(i=0; i<nelem(prefixes); i++) 1761 if(dec->flags & prefixes[i].f) 1762 p += snprintf(p, ep-p, "%s ", prefixes[i].s); 1763 p += snprintf(p, ep-p, "%-6s", dec->name); 1764 for(i=0; i<nelem(dec->arg) && dec->arg[i].op != DA_NONE; i++){ 1765 if(i > 0) 1766 p += snprintf(p, ep-p, ","); 1767 p += snprintf(p, ep-p, " "); 1768 p = fmtarg(p, ep, &dec->arg[i], dec->addr + dec->len); 1769 } 1770 return p - buf; 1771 }