Changeset 9266 in vbox for trunk/src/VBox/Disassembler/testcase
- Timestamp:
- May 31, 2008 2:32:20 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Disassembler/testcase/tstDisasm-2.cpp
r9131 r9266 56 56 57 57 58 /*59 * Non-logging builds doesn't to full formatting so we must do it on our own.60 * This should probably be moved into the disassembler later as it's needed for61 * the vbox debugger as well.62 *63 * Comment in USE_MY_FORMATTER to enable it.64 */65 #define USE_MY_FORMATTER66 67 #ifdef USE_MY_FORMATTER68 static const char g_aszYasmRegGen8x86[8][4] =69 {70 "al\0", "cl\0", "dl\0", "bl\0", "ah\0", "ch\0", "dh\0", "bh\0"71 };72 static const char g_aszYasmRegGen8Amd64[16][5] =73 {74 "al\0\0", "cl\0\0", "dl\0\0", "bl\0\0", "spb\0", "bpb\0", "sib\0", "dib\0", "r8b\0", "r9b\0", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"75 };76 static const char g_aszYasmRegGen16[16][5] =77 {78 "ax\0\0", "cx\0\0", "dx\0\0", "bx\0\0", "sp\0\0", "bp\0\0", "si\0\0", "di\0\0", "r8w\0", "r9w\0", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"79 };80 static const char g_aszYasmRegGen1616[8][6] =81 {82 "bx+si", "bx+di", "bp+si", "bp+di", "si\0\0\0", "di\0\0\0", "bp\0\0\0", "bx\0\0\0"83 };84 static const char g_aszYasmRegGen32[16][5] =85 {86 "eax\0", "ecx\0", "edx\0", "ebx\0", "esp\0", "ebp\0", "esi\0", "edi\0", "r8d\0", "r9d\0", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"87 };88 static const char g_aszYasmRegGen64[16][4] =89 {90 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8\0", "r9\0", "r10", "r11", "r12", "r13", "r14", "r15"91 };92 static const char g_aszYasmRegSeg[6][3] =93 {94 "es", "cs", "ss", "ds", "fs", "gs"95 };96 static const char g_aszYasmRegFP[8][4] =97 {98 "st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7"99 };100 static const char g_aszYasmRegMMX[8][4] =101 {102 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7"103 };104 static const char g_aszYasmRegXMM[16][6] =105 {106 "xmm0\0", "xmm1\0", "xmm2\0", "xmm3\0", "xmm4\0", "xmm5\0", "xmm6\0", "xmm7\0", "xmm8\0", "xmm9\0", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"107 };108 static const char g_aszYasmRegCRx[16][5] =109 {110 "cr0\0", "cr1\0", "cr2\0", "cr3\0", "cr4\0", "cr5\0", "cr6\0", "cr7\0", "cr8\0", "cr9\0", "cr10", "cr11", "cr12", "cr13", "cr14", "cr15"111 };112 static const char g_aszYasmRegDRx[16][5] =113 {114 "dr0\0", "dr1\0", "dr2\0", "dr3\0", "dr4\0", "dr5\0", "dr6\0", "dr7\0", "dr8\0", "dr9\0", "dr10", "dr11", "dr12", "dr13", "dr14", "dr15"115 };116 static const char g_aszYasmRegTRx[16][5] =117 {118 "tr0\0", "tr1\0", "tr2\0", "tr3\0", "tr4\0", "tr5\0", "tr6\0", "tr7\0", "tr8\0", "tr9\0", "tr10", "tr11", "tr12", "tr13", "tr14", "tr15"119 };120 121 122 DECLINLINE(const char *) MyDisasYasmFormatBaseReg(DISCPUSTATE const *pCpu, PCOP_PARAMETER pParam, size_t *pcchReg, bool fReg1616)123 {124 switch (pParam->flags & ( USE_REG_GEN8 | USE_REG_GEN16 | USE_REG_GEN32 | USE_REG_GEN64125 | USE_REG_FP | USE_REG_MMX | USE_REG_XMM | USE_REG_CR126 | USE_REG_DBG | USE_REG_SEG | USE_REG_TEST))127 128 {129 case USE_REG_GEN8:130 if (pCpu->opmode == CPUMODE_64BIT)131 {132 Assert(pParam->base.reg_gen < RT_ELEMENTS(g_aszYasmRegGen8Amd64));133 const char *psz = g_aszYasmRegGen8Amd64[pParam->base.reg_gen];134 *pcchReg = 2 + !!psz[2] + !!psz[3];135 return psz;136 }137 *pcchReg = 2;138 Assert(pParam->base.reg_gen < RT_ELEMENTS(g_aszYasmRegGen8x86));139 return g_aszYasmRegGen8x86[pParam->base.reg_gen];140 141 case USE_REG_GEN16:142 {143 if (fReg1616)144 {145 Assert(pParam->base.reg_gen < RT_ELEMENTS(g_aszYasmRegGen1616));146 const char *psz = g_aszYasmRegGen1616[pParam->base.reg_gen];147 *pcchReg = psz[2] ? 5 : 2;148 return psz;149 }150 151 Assert(pParam->base.reg_gen < RT_ELEMENTS(g_aszYasmRegGen16));152 const char *psz = g_aszYasmRegGen16[pParam->base.reg_gen];153 *pcchReg = 2 + !!psz[2] + !!psz[3];154 return psz;155 }156 157 case USE_REG_GEN32:158 {159 Assert(pParam->base.reg_gen < RT_ELEMENTS(g_aszYasmRegGen32));160 const char *psz = g_aszYasmRegGen32[pParam->base.reg_gen];161 *pcchReg = 2 + !!psz[2] + !!psz[3];162 return psz;163 }164 165 case USE_REG_GEN64:166 {167 Assert(pParam->base.reg_gen < RT_ELEMENTS(g_aszYasmRegGen64));168 const char *psz = g_aszYasmRegGen64[pParam->base.reg_gen];169 *pcchReg = 2 + !!psz[2] + !!psz[3];170 return psz;171 }172 173 case USE_REG_FP:174 {175 Assert(pParam->base.reg_fp < RT_ELEMENTS(g_aszYasmRegFP));176 const char *psz = g_aszYasmRegFP[pParam->base.reg_fp];177 *pcchReg = 3;178 return psz;179 }180 181 case USE_REG_MMX:182 {183 Assert(pParam->base.reg_mmx < RT_ELEMENTS(g_aszYasmRegMMX));184 const char *psz = g_aszYasmRegMMX[pParam->base.reg_mmx];185 *pcchReg = 3;186 return psz;187 }188 189 case USE_REG_XMM:190 {191 Assert(pParam->base.reg_xmm < RT_ELEMENTS(g_aszYasmRegXMM));192 const char *psz = g_aszYasmRegXMM[pParam->base.reg_mmx];193 *pcchReg = 4 + !!psz[4];194 return psz;195 }196 197 case USE_REG_CR:198 {199 Assert(pParam->base.reg_ctrl < RT_ELEMENTS(g_aszYasmRegCRx));200 const char *psz = g_aszYasmRegCRx[pParam->base.reg_ctrl];201 *pcchReg = 3;202 return psz;203 }204 205 case USE_REG_DBG:206 {207 Assert(pParam->base.reg_dbg < RT_ELEMENTS(g_aszYasmRegDRx));208 const char *psz = g_aszYasmRegDRx[pParam->base.reg_dbg];209 *pcchReg = 3;210 return psz;211 }212 213 case USE_REG_SEG:214 {215 Assert(pParam->base.reg_seg < RT_ELEMENTS(g_aszYasmRegCRx));216 const char *psz = g_aszYasmRegSeg[pParam->base.reg_seg];217 *pcchReg = 2;218 return psz;219 }220 221 case USE_REG_TEST:222 {223 Assert(pParam->base.reg_test < RT_ELEMENTS(g_aszYasmRegTRx));224 const char *psz = g_aszYasmRegTRx[pParam->base.reg_test];225 *pcchReg = 3;226 return psz;227 }228 229 default:230 AssertMsgFailed(("%#x\n", pParam->flags));231 *pcchReg = 3;232 return "r??";233 }234 }235 236 DECLINLINE(const char *) MyDisasYasmFormatIndexReg(DISCPUSTATE const *pCpu, PCOP_PARAMETER pParam, size_t *pcchReg)237 {238 switch (pCpu->addrmode)239 {240 case CPUMODE_16BIT:241 {242 Assert(pParam->index.reg_gen < RT_ELEMENTS(g_aszYasmRegGen16));243 const char *psz = g_aszYasmRegGen16[pParam->index.reg_gen];244 *pcchReg = 2 + !!psz[2] + !!psz[3];245 return psz;246 }247 248 case CPUMODE_32BIT:249 {250 Assert(pParam->index.reg_gen < RT_ELEMENTS(g_aszYasmRegGen32));251 const char *psz = g_aszYasmRegGen32[pParam->index.reg_gen];252 *pcchReg = 2 + !!psz[2] + !!psz[3];253 return psz;254 }255 256 case CPUMODE_64BIT:257 {258 Assert(pParam->index.reg_gen < RT_ELEMENTS(g_aszYasmRegGen64));259 const char *psz = g_aszYasmRegGen64[pParam->index.reg_gen];260 *pcchReg = 2 + !!psz[2] + !!psz[3];261 return psz;262 }263 264 default:265 AssertMsgFailed(("%#x %#x\n", pParam->flags, pCpu->addrmode));266 *pcchReg = 3;267 return "r??";268 }269 }270 271 static size_t MyDisasYasmFormat(DISCPUSTATE const *pCpu, char *pszBuf, size_t cchBuf)272 {273 PCOPCODE const pOp = pCpu->pCurInstr;274 size_t cchOutput = 0;275 char *pszDst = pszBuf;276 size_t cchDst = cchBuf;277 278 /* output macros */279 #define PUT_C(ch) \280 do { \281 cchOutput++; \282 if (cchDst > 1) \283 { \284 cchDst--; \285 *pszDst++ = (ch); \286 } \287 } while (0)288 #define PUT_STR(pszSrc, cchSrc) \289 do { \290 cchOutput += (cchSrc); \291 if (cchDst > (cchSrc)) \292 { \293 memcpy(pszDst, (pszSrc), (cchSrc)); \294 pszDst += (cchSrc); \295 cchDst -= (cchSrc); \296 } \297 else if (cchDst > 1) \298 { \299 memcpy(pszDst, (pszSrc), cchDst - 1); \300 pszDst += cchDst - 1; \301 cchDst = 1; \302 } \303 } while (0)304 #define PUT_SZ(sz) \305 PUT_STR((sz), sizeof(sz) - 1)306 #define PUT_PSZ(psz) \307 do { const size_t cchTmp = strlen(psz); PUT_STR((psz), cchTmp); } while (0)308 #define PUT_NUM(cch, fmt, num) \309 do { \310 cchOutput += (cch); \311 if (cchBuf > 1) \312 { \313 const size_t cchTmp = RTStrPrintf(pszDst, cchBuf, fmt, (num)); \314 pszDst += cchTmp; \315 cchBuf -= cchTmp; \316 Assert(cchTmp == (cch) || cchBuf == 1); \317 } \318 } while (0)319 #define PUT_NUM_8(num) PUT_NUM(4, "0%02xh", (uint8_t)(num))320 #define PUT_NUM_16(num) PUT_NUM(6, "0%04xh", (uint16_t)(num))321 #define PUT_NUM_32(num) PUT_NUM(10, "0%08xh", (uint32_t)(num))322 #define PUT_NUM_64(num) PUT_NUM(18, "0%08xh", (uint64_t)(num))323 324 /*325 * Filter out invalid opcodes first as they need special326 * treatment. UD2 is an exception and should be handled normally.327 */328 if ( pOp->opcode == OP_INVALID329 || ( pOp->opcode == OP_ILLUD2330 && (pCpu->prefix & PREFIX_LOCK)))331 {332 333 }334 else335 {336 /*337 * Prefixes338 */339 if (pCpu->prefix & PREFIX_LOCK)340 PUT_SZ("lock ");341 if(pCpu->prefix & PREFIX_REP)342 PUT_SZ("rep ");343 else if(pCpu->prefix & PREFIX_REPNE)344 PUT_SZ("repne ");345 346 /*347 * Adjust the format string to avoid stuff the assembler cannot handle.348 */349 char szTmpFmt[48];350 const char *pszFmt = pOp->pszOpcode;351 switch (pOp->opcode)352 {353 case OP_JECXZ:354 pszFmt = pCpu->opmode == CPUMODE_16BIT ? "jcxz %Jb" : pCpu->opmode == CPUMODE_32BIT ? "jecxz %Jb" : "jrcxz %Jb";355 break;356 case OP_PUSHF:357 pszFmt = pCpu->opmode == CPUMODE_16BIT ? "pushfw" : pCpu->opmode == CPUMODE_32BIT ? "pushfd" : "pushfq";358 break;359 case OP_POPF:360 pszFmt = pCpu->opmode == CPUMODE_16BIT ? "popfw" : pCpu->opmode == CPUMODE_32BIT ? "popfd" : "popfq";361 break;362 case OP_PUSHA:363 pszFmt = pCpu->opmode == CPUMODE_16BIT ? "pushaw" : "pushad";364 break;365 case OP_POPA:366 pszFmt = pCpu->opmode == CPUMODE_16BIT ? "popaw" : "popad";367 break;368 case OP_INSB:369 pszFmt = "insb";370 break;371 case OP_INSWD:372 pszFmt = pCpu->opmode == CPUMODE_16BIT ? "insw" : pCpu->opmode == CPUMODE_32BIT ? "insd" : "insq";373 break;374 case OP_OUTSB:375 pszFmt = "outsb";376 break;377 case OP_OUTSWD:378 pszFmt = pCpu->opmode == CPUMODE_16BIT ? "outsw" : pCpu->opmode == CPUMODE_32BIT ? "outsd" : "outsq";379 break;380 case OP_MOVSB:381 pszFmt = "movsb";382 break;383 case OP_MOVSWD:384 pszFmt = pCpu->opmode == CPUMODE_16BIT ? "movsw" : pCpu->opmode == CPUMODE_32BIT ? "movsd" : "movsq";385 break;386 case OP_CMPSB:387 pszFmt = "cmpsb";388 break;389 case OP_CMPWD:390 pszFmt = pCpu->opmode == CPUMODE_16BIT ? "cmpsw" : pCpu->opmode == CPUMODE_32BIT ? "cmpsd" : "cmpsq";391 break;392 case OP_SCASB:393 pszFmt = "scasb";394 break;395 case OP_SCASWD:396 pszFmt = pCpu->opmode == CPUMODE_16BIT ? "scasw" : pCpu->opmode == CPUMODE_32BIT ? "scasd" : "scasq";397 break;398 case OP_LODSB:399 pszFmt = "lodsb";400 break;401 case OP_LODSWD:402 pszFmt = pCpu->opmode == CPUMODE_16BIT ? "lodsw" : pCpu->opmode == CPUMODE_32BIT ? "lodsd" : "lodsq";403 break;404 case OP_STOSB:405 pszFmt = "stosb";406 break;407 case OP_STOSWD:408 pszFmt = pCpu->opmode == CPUMODE_16BIT ? "stosw" : pCpu->opmode == CPUMODE_32BIT ? "stosd" : "stosq";409 break;410 case OP_CBW:411 pszFmt = pCpu->opmode == CPUMODE_16BIT ? "cbw" : pCpu->opmode == CPUMODE_32BIT ? "cwde" : "cdqe";412 break;413 case OP_CWD:414 pszFmt = pCpu->opmode == CPUMODE_16BIT ? "cwd" : pCpu->opmode == CPUMODE_32BIT ? "cdq" : "cqo";415 break;416 case OP_SHL:417 Assert(pszFmt[3] == '/');418 pszFmt += 4;419 break;420 case OP_XLAT:421 pszFmt = "xlatb";422 break;423 case OP_INT3:424 pszFmt = "int3";425 break;426 427 /*428 * Don't know how to tell yasm to generate complicated nop stuff, so 'db' it.429 */430 case OP_NOP:431 if (pCpu->opcode == 0x90)432 /* fine, fine */;433 else if (pszFmt[sizeof("nop %Ev")] == '/' && pszFmt[sizeof("nop %Ev") + 1] == 'p')434 pszFmt = "prefetch %Eb";435 else if (pCpu->opcode == 0x1f)436 {437 Assert(pCpu->opsize >= 3);438 PUT_SZ("db 00fh, 01fh,");439 PUT_NUM_8(pCpu->ModRM.u);440 for (unsigned i = 3; i < pCpu->opsize; i++)441 {442 PUT_C(',');443 PUT_NUM_8(0x90); ///@todo fixme.444 }445 pszFmt = "";446 }447 break;448 449 default:450 /* ST(X) -> stX (floating point) */451 if (*pszFmt == 'f' && strchr(pszFmt, '('))452 {453 char *pszFmtDst = szTmpFmt;454 char ch;455 do456 {457 ch = *pszFmt++;458 if (ch == 'S' && pszFmt[0] == 'T' && pszFmt[1] == '(')459 {460 *pszFmtDst++ = 's';461 *pszFmtDst++ = 't';462 pszFmt += 2;463 ch = *pszFmt;464 Assert(pszFmt[1] == ')');465 pszFmt += 2;466 *pszFmtDst++ = ch;467 }468 else469 *pszFmtDst++ = ch;470 } while (ch != '\0');471 pszFmt = szTmpFmt;472 }473 break;474 475 /*476 * Horrible hacks.477 */478 case OP_FLD:479 if (pCpu->opcode == 0xdb) /* m80fp workaround. */480 *(int *)&pCpu->param1.param &= ~0x1f; /* make it pure OP_PARM_M */481 break;482 case OP_LAR: /* hack w -> v, probably not correct. */483 *(int *)&pCpu->param2.param &= ~0x1f;484 *(int *)&pCpu->param2.param |= OP_PARM_v;485 break;486 }487 488 /*489 * Formatting context and associated macros.490 */491 PCOP_PARAMETER pParam = &pCpu->param1;492 int iParam = 1;493 494 #define PUT_FAR() \495 do { \496 if ( OP_PARM_VSUBTYPE(pParam->param) == OP_PARM_p \497 && pOp->opcode != OP_LDS /* table bugs? */ \498 && pOp->opcode != OP_LES \499 && pOp->opcode != OP_LFS \500 && pOp->opcode != OP_LGS \501 && pOp->opcode != OP_LSS ) \502 PUT_SZ("far "); \503 } while (0)504 /** @todo mov ah,ch ends up with a byte 'override'... */505 #define PUT_SIZE_OVERRIDE() \506 do { \507 switch (OP_PARM_VSUBTYPE(pParam->param)) \508 { \509 case OP_PARM_v: \510 switch (pCpu->opmode) \511 { \512 case CPUMODE_16BIT: PUT_SZ("word "); break; \513 case CPUMODE_32BIT: PUT_SZ("dword "); break; \514 case CPUMODE_64BIT: PUT_SZ("qword "); break; \515 default: break; \516 } \517 break; \518 case OP_PARM_b: PUT_SZ("byte "); break; \519 case OP_PARM_w: PUT_SZ("word "); break; \520 case OP_PARM_d: PUT_SZ("dword "); break; \521 case OP_PARM_q: PUT_SZ("qword "); break; \522 case OP_PARM_dq: \523 if (OP_PARM_VTYPE(pParam->param) != OP_PARM_W) /* these are 128 bit, pray they are all unambiguous.. */ \524 PUT_SZ("qword "); \525 break; \526 case OP_PARM_p: break; /* see PUT_FAR */ \527 case OP_PARM_s: if (pParam->flags & USE_REG_FP) PUT_SZ("tword "); break; /* ?? */ \528 case OP_PARM_z: break; \529 case OP_PARM_NONE: \530 if ( OP_PARM_VTYPE(pParam->param) == OP_PARM_M \531 && ((pParam->flags & USE_REG_FP) || pOp->opcode == OP_FLD)) \532 PUT_SZ("tword "); \533 break; \534 default: break; /*no pointer type specified/necessary*/ \535 } \536 } while (0)537 static const char s_szSegPrefix[6][4] = { "es:", "cs:", "ss:", "ds:", "fs:", "gs:" };538 #define PUT_SEGMENT_OVERRIDE() \539 do { \540 if (pCpu->prefix & PREFIX_SEG) \541 PUT_STR(s_szSegPrefix[pCpu->prefix_seg], 3); \542 } while (0)543 544 545 /*546 * Segment prefixing for instructions that doesn't do memory access.547 */548 if ( (pCpu->prefix & PREFIX_SEG)549 && !DIS_IS_EFFECTIVE_ADDR(pCpu->param1.flags)550 && !DIS_IS_EFFECTIVE_ADDR(pCpu->param2.flags)551 && !DIS_IS_EFFECTIVE_ADDR(pCpu->param3.flags))552 {553 PUT_STR(s_szSegPrefix[pCpu->prefix_seg], 2);554 PUT_C(' ');555 }556 557 558 /*559 * The formatting loop.560 */561 char ch;562 while ((ch = *pszFmt++) != '\0')563 {564 if (ch == '%')565 {566 ch = *pszFmt++;567 switch (ch)568 {569 /*570 * ModRM - Register only.571 */572 case 'C': /* Control register (ParseModRM / UseModRM). */573 case 'D': /* Debug register (ParseModRM / UseModRM). */574 case 'G': /* ModRM selects general register (ParseModRM / UseModRM). */575 case 'S': /* ModRM byte selects a segment register (ParseModRM / UseModRM). */576 case 'T': /* ModRM byte selects a test register (ParseModRM / UseModRM). */577 case 'V': /* ModRM byte selects an XMM/SSE register (ParseModRM / UseModRM). */578 case 'P': /* ModRM byte selects MMX register (ParseModRM / UseModRM). */579 {580 pszFmt += RT_C_IS_ALPHA(pszFmt[0]) ? RT_C_IS_ALPHA(pszFmt[1]) ? 2 : 1 : 0;581 Assert(!(pParam->flags & (USE_INDEX | USE_SCALE) /* No SIB here... */));582 Assert(!(pParam->flags & (USE_DISPLACEMENT8 | USE_DISPLACEMENT16 | USE_DISPLACEMENT32 | USE_DISPLACEMENT64 | USE_RIPDISPLACEMENT32)));583 584 size_t cchReg;585 const char *pszReg = MyDisasYasmFormatBaseReg(pCpu, pParam, &cchReg, 0 /* pCpu->addrmode == CPUMODE_16BIT */);586 PUT_STR(pszReg, cchReg);587 break;588 }589 590 /*591 * ModRM - Register or memory.592 */593 case 'E': /* ModRM specifies parameter (ParseModRM / UseModRM / UseSIB). */594 case 'Q': /* ModRM byte selects MMX register or memory address (ParseModRM / UseModRM). */595 case 'R': /* ModRM byte may only refer to a general register (ParseModRM / UseModRM). */596 case 'W': /* ModRM byte selects an XMM/SSE register or a memory address (ParseModRM / UseModRM). */597 case 'M': /* ModRM may only refer to memory (ParseModRM / UseModRM). */598 {599 pszFmt += RT_C_IS_ALPHA(pszFmt[0]) ? RT_C_IS_ALPHA(pszFmt[1]) ? 2 : 1 : 0;600 601 PUT_FAR();602 if (DIS_IS_EFFECTIVE_ADDR(pParam->flags))603 {604 /* Work around mov seg,[mem16] and mov [mem16],seg as these always make a 16-bit mem605 while the register variants deals with 16, 32 & 64 in the normal fashion. */606 if ( pParam->param != OP_PARM_Ev607 || pOp->opcode != OP_MOV608 || ( pOp->param1 != OP_PARM_Sw609 && pOp->param2 != OP_PARM_Sw))610 PUT_SIZE_OVERRIDE();611 PUT_C('[');612 }613 if (pParam->flags & (USE_DISPLACEMENT8 | USE_DISPLACEMENT16 | USE_DISPLACEMENT32 | USE_DISPLACEMENT64 | USE_RIPDISPLACEMENT32))614 {615 if ( (pParam->flags & USE_DISPLACEMENT8)616 && !pParam->disp8)617 PUT_SZ("byte ");618 else if ( (pParam->flags & USE_DISPLACEMENT16)619 && (int8_t)pParam->disp16 == (int16_t)pParam->disp16)620 PUT_SZ("word ");621 else if ( (pParam->flags & USE_DISPLACEMENT32)622 && (int8_t)pParam->disp32 == (int32_t)pParam->disp32)623 PUT_SZ("dword ");624 }625 if (DIS_IS_EFFECTIVE_ADDR(pParam->flags))626 PUT_SEGMENT_OVERRIDE();627 628 bool fBase = (pParam->flags & USE_BASE) /* When exactly is USE_BASE supposed to be set? disasmModRMReg doesn't set it. */629 || ( (pParam->flags & (USE_REG_GEN8 | USE_REG_GEN16 | USE_REG_GEN32 | USE_REG_GEN64))630 && !DIS_IS_EFFECTIVE_ADDR(pParam->flags));631 if (fBase)632 {633 size_t cchReg;634 const char *pszReg = MyDisasYasmFormatBaseReg(pCpu, pParam, &cchReg, 0 /*pCpu->addrmode == CPUMODE_16BIT*/);635 PUT_STR(pszReg, cchReg);636 }637 638 if (pParam->flags & USE_INDEX)639 {640 if (fBase)641 PUT_C('+');642 643 size_t cchReg;644 const char *pszReg = MyDisasYasmFormatIndexReg(pCpu, pParam, &cchReg);645 PUT_STR(pszReg, cchReg);646 647 if (pParam->flags & USE_SCALE)648 {649 PUT_C('*');650 PUT_C('0' + pParam->scale);651 }652 }653 else654 Assert(!(pParam->flags & USE_SCALE));655 656 if (pParam->flags & (USE_DISPLACEMENT8 | USE_DISPLACEMENT16 | USE_DISPLACEMENT32 | USE_DISPLACEMENT64 | USE_RIPDISPLACEMENT32))657 {658 Assert(!(pParam->flags & USE_DISPLACEMENT64));659 int32_t off;660 if (pParam->flags & USE_DISPLACEMENT8)661 off = pParam->disp8;662 else if (pParam->flags & USE_DISPLACEMENT16)663 off = pParam->disp16;664 else if (pParam->flags & (USE_DISPLACEMENT32 | USE_RIPDISPLACEMENT32))665 off = pParam->disp32;666 667 if (fBase || (pParam->flags & USE_INDEX))668 PUT_C(off >= 0 ? '+' : '-');669 670 if (off < 0)671 off = -off;672 if (pParam->flags & USE_DISPLACEMENT8)673 PUT_NUM_8( off);674 else if (pParam->flags & USE_DISPLACEMENT16)675 PUT_NUM_16(off);676 else if (pParam->flags & USE_DISPLACEMENT32)677 PUT_NUM_32(off);678 else679 {680 PUT_NUM_32(off);681 PUT_SZ(" wrt rip"); //??682 }683 }684 685 if (DIS_IS_EFFECTIVE_ADDR(pParam->flags))686 PUT_C(']');687 break;688 }689 690 case 'F': /* Eflags register (0 - popf/pushf only, avoided in adjustments above). */691 AssertFailed();692 break;693 694 case 'I': /* Immediate data (ParseImmByte, ParseImmByteSX, ParseImmV, ParseImmUshort, ParseImmZ). */695 Assert(*pszFmt == 'b' || *pszFmt == 'v' || *pszFmt == 'w' || *pszFmt == 'z'); pszFmt++;696 switch (pParam->flags & ( USE_IMMEDIATE8 | USE_IMMEDIATE16 | USE_IMMEDIATE32 | USE_IMMEDIATE64697 | USE_IMMEDIATE16_SX8 | USE_IMMEDIATE32_SX8))698 {699 case USE_IMMEDIATE8:700 if ( (pOp->param1 >= OP_PARM_REG_GEN8_START && pOp->param1 <= OP_PARM_REG_GEN8_END)701 || (pOp->param2 >= OP_PARM_REG_GEN8_START && pOp->param2 <= OP_PARM_REG_GEN8_END)702 )703 PUT_SZ("strict byte ");704 PUT_NUM_8(pParam->parval);705 break;706 707 case USE_IMMEDIATE16:708 if ( (int8_t)pParam->parval == (int16_t)pParam->parval709 || (pOp->param1 >= OP_PARM_REG_GEN16_START && pOp->param1 <= OP_PARM_REG_GEN16_END)710 || (pOp->param2 >= OP_PARM_REG_GEN16_START && pOp->param2 <= OP_PARM_REG_GEN16_END)711 || pCpu->mode != pCpu->opmode712 )713 {714 if (OP_PARM_VSUBTYPE(pParam->param) == OP_PARM_b)715 PUT_SZ("strict byte ");716 else if (OP_PARM_VSUBTYPE(pParam->param) == OP_PARM_v)717 PUT_SZ("strict word ");718 }719 PUT_NUM_16(pParam->parval);720 break;721 722 case USE_IMMEDIATE16_SX8:723 PUT_SZ("strict byte ");724 PUT_NUM_16(pParam->parval);725 break;726 727 case USE_IMMEDIATE32:728 if ( (int8_t)pParam->parval == (int32_t)pParam->parval729 || (pOp->param1 >= OP_PARM_REG_GEN32_START && pOp->param1 <= OP_PARM_REG_GEN32_END)730 || (pOp->param2 >= OP_PARM_REG_GEN32_START && pOp->param2 <= OP_PARM_REG_GEN32_END)731 || pCpu->opmode != (pCpu->mode == CPUMODE_16BIT ? CPUMODE_16BIT : CPUMODE_32BIT) /* not perfect */732 )733 {734 if (OP_PARM_VSUBTYPE(pParam->param) == OP_PARM_b)735 PUT_SZ("strict byte ");736 else if (OP_PARM_VSUBTYPE(pParam->param) == OP_PARM_v)737 PUT_SZ("strict dword ");738 }739 PUT_NUM_32(pParam->parval);740 break;741 742 case USE_IMMEDIATE32_SX8:743 PUT_SZ("strict byte ");744 PUT_NUM_32(pParam->parval);745 break;746 747 case USE_IMMEDIATE64:748 PUT_NUM_64(pParam->parval);749 break;750 751 default:752 AssertFailed();753 break;754 }755 break;756 757 case 'J': /* Relative jump offset (ParseImmBRel + ParseImmVRel). */758 {759 int32_t offDisplacement;760 Assert(iParam == 1);761 bool fPrefix = pOp->opcode != OP_CALL762 && pOp->opcode != OP_LOOP763 && pOp->opcode != OP_LOOPE764 && pOp->opcode != OP_LOOPNE765 && pOp->opcode != OP_JECXZ;766 767 if (pParam->flags & USE_IMMEDIATE8_REL)768 {769 if (fPrefix)770 PUT_SZ("short ");771 offDisplacement = (int8_t)pParam->parval;772 Assert(*pszFmt == 'b'); pszFmt++;773 }774 else if (pParam->flags & USE_IMMEDIATE16_REL)775 {776 if (fPrefix)777 PUT_SZ("near ");778 offDisplacement = (int16_t)pParam->parval;779 Assert(*pszFmt == 'v'); pszFmt++;780 }781 else782 {783 if (fPrefix)784 PUT_SZ("near ");785 offDisplacement = (int32_t)pParam->parval;786 Assert(pParam->flags & USE_IMMEDIATE32_REL);787 Assert(*pszFmt == 'v'); pszFmt++;788 }789 790 RTUINTPTR uTrgAddr = pCpu->opaddr + pCpu->opsize + offDisplacement;791 if (pCpu->mode == CPUMODE_16BIT)792 PUT_NUM_16(uTrgAddr);793 else if (pCpu->mode == CPUMODE_32BIT)794 PUT_NUM_32(uTrgAddr);795 else796 PUT_NUM_64(uTrgAddr);797 break;798 }799 800 case 'A': /* Direct (jump/call) address (ParseImmAddr). */801 Assert(*pszFmt == 'p'); pszFmt++;802 PUT_FAR();803 PUT_SIZE_OVERRIDE();804 PUT_SEGMENT_OVERRIDE();805 switch (pParam->flags & (USE_IMMEDIATE_ADDR_16_16 | USE_IMMEDIATE_ADDR_16_32 | USE_DISPLACEMENT64 | USE_DISPLACEMENT32 | USE_DISPLACEMENT16))806 {807 case USE_IMMEDIATE_ADDR_16_16:808 PUT_NUM_16(pParam->parval >> 16);809 PUT_C(':');810 PUT_NUM_16(pParam->parval);811 break;812 case USE_IMMEDIATE_ADDR_16_32:813 PUT_NUM_16(pParam->parval >> 32);814 PUT_C(':');815 PUT_NUM_32(pParam->parval);816 break;817 case USE_DISPLACEMENT16:818 PUT_NUM_16(pParam->parval);819 break;820 case USE_DISPLACEMENT32:821 PUT_NUM_32(pParam->parval);822 break;823 case USE_DISPLACEMENT64:824 PUT_NUM_64(pParam->parval);825 break;826 default:827 AssertFailed();828 break;829 }830 break;831 832 case 'O': /* No ModRM byte (ParseImmAddr). */833 Assert(*pszFmt == 'b' || *pszFmt == 'v'); pszFmt++;834 PUT_FAR();835 PUT_SIZE_OVERRIDE();836 PUT_C('[');837 PUT_SEGMENT_OVERRIDE();838 switch (pParam->flags & (USE_IMMEDIATE_ADDR_16_16 | USE_IMMEDIATE_ADDR_16_32 | USE_DISPLACEMENT64 | USE_DISPLACEMENT32 | USE_DISPLACEMENT16))839 {840 case USE_IMMEDIATE_ADDR_16_16:841 PUT_NUM_16(pParam->parval >> 16);842 PUT_C(':');843 PUT_NUM_16(pParam->parval);844 break;845 case USE_IMMEDIATE_ADDR_16_32:846 PUT_NUM_16(pParam->parval >> 32);847 PUT_C(':');848 PUT_NUM_32(pParam->parval);849 break;850 case USE_DISPLACEMENT16:851 PUT_NUM_16(pParam->disp16);852 break;853 case USE_DISPLACEMENT32:854 PUT_NUM_32(pParam->disp32);855 break;856 case USE_DISPLACEMENT64:857 PUT_NUM_64(pParam->disp64);858 break;859 default:860 AssertFailed();861 break;862 }863 PUT_C(']');864 break;865 866 case 'X': /* DS:SI (ParseXb, ParseXv). */867 case 'Y': /* ES:DI (ParseYb, ParseYv). */868 {869 Assert(*pszFmt == 'b' || *pszFmt == 'v'); pszFmt++;870 PUT_FAR();871 PUT_SIZE_OVERRIDE();872 PUT_C('[');873 if (pParam->flags & USE_POINTER_DS_BASED)874 PUT_SZ("ds:");875 else876 PUT_SZ("es:");877 878 size_t cchReg;879 const char *pszReg = MyDisasYasmFormatBaseReg(pCpu, pParam, &cchReg, 0);880 PUT_STR(pszReg, cchReg);881 PUT_C(']');882 break;883 }884 885 case 'e': /* Register based on operand size (e.g. %eAX) (ParseFixedReg). */886 {887 Assert(RT_C_IS_ALPHA(pszFmt[0]) && RT_C_IS_ALPHA(pszFmt[1]) && !RT_C_IS_ALPHA(pszFmt[2])); pszFmt += 2;888 size_t cchReg;889 const char *pszReg = MyDisasYasmFormatBaseReg(pCpu, pParam, &cchReg, 0);890 PUT_STR(pszReg, cchReg);891 break;892 }893 894 default:895 AssertMsgFailed(("%c%s!\n", ch, pszFmt));896 break;897 }898 AssertMsg(*pszFmt == ',' || *pszFmt == '\0', ("%c%s\n", ch, pszFmt));899 }900 else901 {902 PUT_C(ch);903 if (ch == ',')904 {905 Assert(*pszFmt != ' ');906 PUT_C(' ');907 switch (++iParam)908 {909 case 2: pParam = &pCpu->param2; break;910 case 3: pParam = &pCpu->param3; break;911 default: pParam = NULL; break;912 }913 }914 }915 } /* while more to format */916 }917 918 919 /* Terminate it - on overflow we'll have reserved one byte for this. */920 if (cchDst > 0)921 *pszDst = '\0';922 923 /* clean up macros */924 #undef PUT_PSZ925 #undef PUT_SZ926 #undef PUT_STR927 #undef PUT_C928 return cchOutput;929 }930 #endif931 932 58 933 59 /** … … 950 76 { 951 77 char szTmp[256]; 952 #if ndef USE_MY_FORMATTER78 #if 0 953 79 /* a very quick hack. */ 954 80 strcpy(szTmp, RTStrStripL(strchr(pState->szLine, ':') + 1)); … … 967 93 *pszEnd = '\0'; 968 94 969 #else /* USE_MY_FORMATTER */ 970 size_t cch = MyDisasYasmFormat(&pState->Cpu, szTmp, sizeof(szTmp)); 95 #else 96 size_t cch = DISFormatYasmEx(&pState->Cpu, szTmp, sizeof(szTmp), 97 DIS_FMT_FLAGS_ADDR_RIGHT | DIS_FMT_FLAGS_ADDR_COMMENT 98 | DIS_FMT_FLAGS_BYTES_RIGHT | DIS_FMT_FLAGS_BYTES_COMMENT | DIS_FMT_FLAGS_BYTES_SPACED, 99 NULL, NULL); 971 100 Assert(cch < sizeof(szTmp)); 972 101 while (cch < 71) 973 102 szTmp[cch++] = ' '; 974 103 szTmp[cch] = '\0'; 975 #endif /* USE_MY_FORMATTER */104 #endif 976 105 977 106 RTPrintf(" %s ; %08llu %s", szTmp, pState->uAddress, pState->szLine);
Note:
See TracChangeset
for help on using the changeset viewer.