VirtualBox

Ignore:
Timestamp:
May 31, 2008 2:32:20 AM (17 years ago)
Author:
vboxsync
Message:

DISFormatYasm(Ex).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Disassembler/testcase/tstDisasm-2.cpp

    r9131 r9266  
    5656
    5757
    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 for
    61  * the vbox debugger as well.
    62  *
    63  * Comment in USE_MY_FORMATTER to enable it.
    64  */
    65 #define USE_MY_FORMATTER
    66 
    67 #ifdef USE_MY_FORMATTER
    68 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_GEN64
    125                              | USE_REG_FP   | USE_REG_MMX   | USE_REG_XMM   | USE_REG_CR
    126                              | 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 special
    326      * treatment. UD2 is an exception and should be handled normally.
    327      */
    328     if (    pOp->opcode == OP_INVALID
    329         ||  (   pOp->opcode == OP_ILLUD2
    330              && (pCpu->prefix & PREFIX_LOCK)))
    331     {
    332 
    333     }
    334     else
    335     {
    336         /*
    337          * Prefixes
    338          */
    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                     do
    456                     {
    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                         else
    469                             *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 mem
    605                                while the register variants deals with 16, 32 & 64 in the normal fashion. */
    606                             if (    pParam->param != OP_PARM_Ev
    607                                 ||  pOp->opcode != OP_MOV
    608                                 ||  (   pOp->param1 != OP_PARM_Sw
    609                                      && 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                         else
    654                             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                             else
    679                             {
    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_IMMEDIATE64
    697                                                  | 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->parval
    709                                     ||  (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->opmode
    712                                     )
    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->parval
    729                                     ||  (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_CALL
    762                                     && pOp->opcode != OP_LOOP
    763                                     && pOp->opcode != OP_LOOPE
    764                                     && pOp->opcode != OP_LOOPNE
    765                                     && 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                         else
    782                         {
    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                         else
    796                             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                         else
    876                             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             else
    901             {
    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_PSZ
    925 #undef PUT_SZ
    926 #undef PUT_STR
    927 #undef PUT_C
    928     return cchOutput;
    929 }
    930 #endif
    931 
    93258
    93359/**
     
    95076{
    95177    char szTmp[256];
    952 #ifndef USE_MY_FORMATTER
     78#if 0
    95379    /* a very quick hack. */
    95480    strcpy(szTmp, RTStrStripL(strchr(pState->szLine, ':') + 1));
     
    96793    *pszEnd = '\0';
    96894
    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);
    971100    Assert(cch < sizeof(szTmp));
    972101    while (cch < 71)
    973102        szTmp[cch++] = ' ';
    974103    szTmp[cch] = '\0';
    975 #endif /* USE_MY_FORMATTER */
     104#endif
    976105
    977106    RTPrintf("    %s ; %08llu %s", szTmp, pState->uAddress, pState->szLine);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette