DisasmFormatYasm.cpp revision 6aaf719e54eb3264fb7330e1a3bb41417dff7ab5
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * VBox Disassembler - Yasm(/Nasm) Style Formatter.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Copyright (C) 2008-2012 Oracle Corporation
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * available from http://www.virtualbox.org. This file is free software;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * you can redistribute it and/or modify it under the terms of the GNU
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * General Public License (GPL) as published by the Free Software
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/*******************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync* Header Files *
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync*******************************************************************************/
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/*******************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync* Global Variables *
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync*******************************************************************************/
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic const char g_szSpaces[] =
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync "al\0\0", "cl\0\0", "dl\0\0", "bl\0\0", "ah\0\0", "ch\0\0", "dh\0\0", "bh\0\0", "r8b\0", "r9b\0", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b", "spl\0", "bpl\0", "sil\0", "dil\0"
"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"
"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"
"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8\0", "r9\0", "r10", "r11", "r12", "r13", "r14", "r15"
"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"
"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"
"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"
"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"
case DISUSE_REG_GEN8:
return psz;
case DISUSE_REG_GEN16:
return psz;
case DISUSE_REG_GEN32:
return psz;
case DISUSE_REG_GEN64:
return psz;
case DISUSE_REG_FP:
return psz;
case DISUSE_REG_MMX:
return psz;
case DISUSE_REG_XMM:
return psz;
case DISUSE_REG_CR:
return psz;
case DISUSE_REG_DBG:
return psz;
case DISUSE_REG_SEG:
return psz;
case DISUSE_REG_TEST:
return psz;
case DISCPUMODE_16BIT:
return psz;
case DISCPUMODE_32BIT:
return psz;
case DISCPUMODE_64BIT:
return psz;
cchOutput++; \
cchDst--; \
if (off != 0) \
if (pfnGetSymbol) \
case OP_JECXZ:
pszFmt = pDis->uOpMode == DISCPUMODE_16BIT ? "jcxz %Jb" : pDis->uOpMode == DISCPUMODE_32BIT ? "jecxz %Jb" : "jrcxz %Jb";
case OP_PUSHF:
pszFmt = pDis->uOpMode == DISCPUMODE_16BIT ? "pushfw" : pDis->uOpMode == DISCPUMODE_32BIT ? "pushfd" : "pushfq";
case OP_POPF:
pszFmt = pDis->uOpMode == DISCPUMODE_16BIT ? "popfw" : pDis->uOpMode == DISCPUMODE_32BIT ? "popfd" : "popfq";
case OP_PUSHA:
case OP_POPA:
case OP_INSB:
case OP_INSWD:
pszFmt = pDis->uOpMode == DISCPUMODE_16BIT ? "insw" : pDis->uOpMode == DISCPUMODE_32BIT ? "insd" : "insq";
case OP_OUTSB:
case OP_OUTSWD:
pszFmt = pDis->uOpMode == DISCPUMODE_16BIT ? "outsw" : pDis->uOpMode == DISCPUMODE_32BIT ? "outsd" : "outsq";
case OP_MOVSB:
case OP_MOVSWD:
pszFmt = pDis->uOpMode == DISCPUMODE_16BIT ? "movsw" : pDis->uOpMode == DISCPUMODE_32BIT ? "movsd" : "movsq";
case OP_CMPSB:
case OP_CMPWD:
pszFmt = pDis->uOpMode == DISCPUMODE_16BIT ? "cmpsw" : pDis->uOpMode == DISCPUMODE_32BIT ? "cmpsd" : "cmpsq";
case OP_SCASB:
case OP_SCASWD:
pszFmt = pDis->uOpMode == DISCPUMODE_16BIT ? "scasw" : pDis->uOpMode == DISCPUMODE_32BIT ? "scasd" : "scasq";
case OP_LODSB:
case OP_LODSWD:
pszFmt = pDis->uOpMode == DISCPUMODE_16BIT ? "lodsw" : pDis->uOpMode == DISCPUMODE_32BIT ? "lodsd" : "lodsq";
case OP_STOSB:
case OP_STOSWD:
pszFmt = pDis->uOpMode == DISCPUMODE_16BIT ? "stosw" : pDis->uOpMode == DISCPUMODE_32BIT ? "stosd" : "stosq";
case OP_CBW:
pszFmt = pDis->uOpMode == DISCPUMODE_16BIT ? "cbw" : pDis->uOpMode == DISCPUMODE_32BIT ? "cwde" : "cdqe";
case OP_CWD:
pszFmt = pDis->uOpMode == DISCPUMODE_16BIT ? "cwd" : pDis->uOpMode == DISCPUMODE_32BIT ? "cdq" : "cqo";
case OP_SHL:
case OP_XLAT:
case OP_INT3:
case OP_NOP:
char ch;
case OP_FLD:
#define PUT_FAR() \
/** @todo drop the work/dword/qword override when the src/dst is a register (except for movsx/movzx). */
#define PUT_SIZE_OVERRIDE() \
case OP_PARM_v: \
case OP_PARM_dq: \
if (OP_PARM_VTYPE(pParam->fParam) != OP_PARM_W) /* these are 128 bit, pray they are all unambiguous.. */ \
case OP_PARM_z: break; \
case OP_PARM_NONE: \
#define PUT_SEGMENT_OVERRIDE() \
char ch;
switch (ch)
Assert(!(pParam->fUse & (DISUSE_DISPLACEMENT8 | DISUSE_DISPLACEMENT16 | DISUSE_DISPLACEMENT32 | DISUSE_DISPLACEMENT64 | DISUSE_RIPDISPLACEMENT32)));
PUT_FAR();
&& (fUse & (DISUSE_DISPLACEMENT8 | DISUSE_DISPLACEMENT16 | DISUSE_DISPLACEMENT32 | DISUSE_DISPLACEMENT64 | DISUSE_RIPDISPLACEMENT32)))
bool fBase = (fUse & DISUSE_BASE) /* When exactly is DISUSE_BASE supposed to be set? disasmModRMReg doesn't set it. */
| DISUSE_REG_TEST ))
if (fBase)
if (fBase)
if (fUse & (DISUSE_DISPLACEMENT8 | DISUSE_DISPLACEMENT16 | DISUSE_DISPLACEMENT32 | DISUSE_DISPLACEMENT64 | DISUSE_RIPDISPLACEMENT32))
AssertFailed();
off2 = 0;
if (off2 < 0)
AssertFailed();
case 'I': /* Immediate data (ParseImmByte, ParseImmByteSX, ParseImmV, ParseImmUshort, ParseImmZ). */
switch (pParam->fUse & ( DISUSE_IMMEDIATE8 | DISUSE_IMMEDIATE16 | DISUSE_IMMEDIATE32 | DISUSE_IMMEDIATE64
case DISUSE_IMMEDIATE8:
case DISUSE_IMMEDIATE16:
case DISUSE_IMMEDIATE16_SX8:
case DISUSE_IMMEDIATE32:
if ( pDis->uOpMode != (pDis->uCpuMode == DISCPUMODE_16BIT ? DISCPUMODE_16BIT : DISCPUMODE_32BIT) /* not perfect */
case DISUSE_IMMEDIATE32_SX8:
case DISUSE_IMMEDIATE64_SX8:
case DISUSE_IMMEDIATE64:
AssertFailed();
if (fPrefix)
if (fPrefix)
if (fPrefix)
PUT_FAR();
switch (pParam->fUse & (DISUSE_IMMEDIATE_ADDR_16_16 | DISUSE_IMMEDIATE_ADDR_16_32 | DISUSE_DISPLACEMENT64 | DISUSE_DISPLACEMENT32 | DISUSE_DISPLACEMENT16))
if (pfnGetSymbol)
rc = pfnGetSymbol(pDis, DIS_FMT_SEL_FROM_VALUE(pParam->uValue >> 16), (uint16_t)pParam->uValue, szSymbol, sizeof(szSymbol), &off, pvUser);
if (pfnGetSymbol)
rc = pfnGetSymbol(pDis, DIS_FMT_SEL_FROM_VALUE(pParam->uValue >> 16), (uint32_t)pParam->uValue, szSymbol, sizeof(szSymbol), &off, pvUser);
case DISUSE_DISPLACEMENT16:
if (pfnGetSymbol)
rc = pfnGetSymbol(pDis, DIS_FMT_SEL_FROM_REG(DISSELREG_CS), (uint16_t)pParam->uValue, szSymbol, sizeof(szSymbol), &off, pvUser);
case DISUSE_DISPLACEMENT32:
if (pfnGetSymbol)
rc = pfnGetSymbol(pDis, DIS_FMT_SEL_FROM_REG(DISSELREG_CS), (uint32_t)pParam->uValue, szSymbol, sizeof(szSymbol), &off, pvUser);
case DISUSE_DISPLACEMENT64:
if (pfnGetSymbol)
rc = pfnGetSymbol(pDis, DIS_FMT_SEL_FROM_REG(DISSELREG_CS), (uint64_t)pParam->uValue, szSymbol, sizeof(szSymbol), &off, pvUser);
AssertFailed();
PUT_FAR();
switch (pParam->fUse & (DISUSE_IMMEDIATE_ADDR_16_16 | DISUSE_IMMEDIATE_ADDR_16_32 | DISUSE_DISPLACEMENT64 | DISUSE_DISPLACEMENT32 | DISUSE_DISPLACEMENT16))
if (pfnGetSymbol)
rc = pfnGetSymbol(pDis, DIS_FMT_SEL_FROM_VALUE(pParam->uValue >> 16), (uint16_t)pParam->uValue, szSymbol, sizeof(szSymbol), &off, pvUser);
if (pfnGetSymbol)
rc = pfnGetSymbol(pDis, DIS_FMT_SEL_FROM_VALUE(pParam->uValue >> 16), (uint32_t)pParam->uValue, szSymbol, sizeof(szSymbol), &off, pvUser);
case DISUSE_DISPLACEMENT16:
if (pfnGetSymbol)
rc = pfnGetSymbol(pDis, DIS_FMT_SEL_FROM_REG(DISSELREG_CS), pParam->uDisp.u16, szSymbol, sizeof(szSymbol), &off, pvUser);
case DISUSE_DISPLACEMENT32:
if (pfnGetSymbol)
rc = pfnGetSymbol(pDis, DIS_FMT_SEL_FROM_REG(DISSELREG_CS), pParam->uDisp.u32, szSymbol, sizeof(szSymbol), &off, pvUser);
case DISUSE_DISPLACEMENT64:
if (pfnGetSymbol)
rc = pfnGetSymbol(pDis, DIS_FMT_SEL_FROM_REG(DISSELREG_CS), pParam->uDisp.u64, szSymbol, sizeof(szSymbol), &off, pvUser);
AssertFailed();
PUT_FAR();
switch (++iParam)
if (cchDst > 0)
return cchOutput;
return DISFormatYasmEx(pDis, pszBuf, cchBuf, 0 /* fFlags */, NULL /* pfnGetSymbol */, NULL /* pvUser */);
uint32_t f;
f = DISPREFIX_LOCK;
f = DISPREFIX_SEG;
f = DISPREFIX_OPSIZE;
f = DISPREFIX_ADDRSIZE;
if (fPrefixes & f)
fPrefixes |= f;
if (fPrefixes)
case OP_NOP:
case OP_JMP:
case OP_JO:
case OP_JNO:
case OP_JC:
case OP_JNC:
case OP_JE:
case OP_JNE:
case OP_JBE:
case OP_JNBE:
case OP_JS:
case OP_JNS:
case OP_JP:
case OP_JNP:
case OP_JL:
case OP_JNL:
case OP_JLE:
case OP_JNLE:
case OP_POP:
case OP_PUSH:
case OP_POPA:
case OP_POPF:
case OP_PUSHA:
case OP_PUSHF:
case OP_ADD:
case OP_OR:
case OP_ADC:
case OP_SBB:
case OP_AND:
case OP_SUB:
case OP_XOR:
case OP_CMP:
if (fPrefixes)
case OP_STI:
case OP_STC:
case OP_CLI:
case OP_CLD:
case OP_CLC:
case OP_INT:
case OP_INT3:
case OP_INTO:
case OP_HLT:
case OP_FIADD:
case OP_FIMUL:
case OP_FISUB:
case OP_FISUBR:
case OP_FIDIV:
case OP_FIDIVR:
case OP_MOV:
case OP_ADD:
case OP_OR:
case OP_ADC:
case OP_SBB:
case OP_AND:
case OP_SUB:
case OP_XOR:
case OP_CMP:
case OP_DEC:
case OP_INC:
case OP_POP:
case OP_PUSH:
case OP_MOV:
case OP_SHL:
case OP_SHR:
case OP_SAR:
case OP_RCL:
case OP_RCR:
case OP_ROL:
case OP_ROR:
case OP_ADD:
case OP_OR:
case OP_ADC:
case OP_SBB:
case OP_AND:
case OP_SUB:
case OP_XOR:
case OP_CMP:
case OP_SETO:
case OP_SETNO:
case OP_SETC:
case OP_SETNC:
case OP_SETE:
case OP_SETNE:
case OP_SETBE:
case OP_SETNBE:
case OP_SETS:
case OP_SETNS:
case OP_SETP:
case OP_SETNP:
case OP_SETL:
case OP_SETNL:
case OP_SETLE:
case OP_SETNLE: