// vex encoded general purpose register void disassembler::By(const x86_insn *insn) { if (insn->os_64) dis_sprintf("%s", general_64bit_regname[insn->vex_vvv]); else dis_sprintf("%s", general_32bit_regname[insn->vex_vvv]); }
void disassembler::STi(const x86_insn *insn) { if (intel_mode) dis_sprintf ("st(%d)", insn->rm & 7); else dis_sprintf("%%st(%d)", insn->rm & 7); }
void disassembler::Nq(const x86_insn *insn) { if (intel_mode) dis_sprintf ("mm%d", insn->rm & 0x7); else dis_sprintf("%%mm%d", insn->rm & 0x7); }
// general purpose register void disassembler::Gb(const x86_insn *insn) { if (insn->nnn < 4 || insn->extend8b) dis_sprintf("%s", general_8bit_regname_rex[insn->nnn]); else dis_sprintf("%s", general_8bit_regname[insn->nnn]); }
void disassembler::OP_sY(const x86_insn *insn, unsigned size) { const char *rdi, *seg; if (insn->as_64) { rdi = general_64bit_regname[rDI_REG]; } else { if (insn->as_32) rdi = general_32bit_regname[rDI_REG]; else rdi = general_16bit_regname[rDI_REG]; } print_datasize(size); if (insn->is_seg_override()) seg = segment_name[insn->seg_override]; else seg = segment_name[DS_REG]; if (intel_mode) dis_sprintf("%s:[%s]", seg, rdi); else dis_sprintf("%s:(%s)", seg, rdi); }
// floating point void disassembler::ST0(const x86_insn *insn) { if (intel_mode) dis_sprintf ("st(0)"); else dis_sprintf("%%st(0)"); }
// debug register void disassembler::Dd(const x86_insn *insn) { if (intel_mode) dis_sprintf ("dr%d", insn->nnn); else dis_sprintf("%%dr%d", insn->nnn); }
// 8-bit general purpose register void disassembler::Reg8(const x86_insn *insn) { unsigned reg = (insn->b1 & 7) | insn->rex_b; if (reg < 4 || insn->extend8b) dis_sprintf("%s", general_8bit_regname_rex[reg]); else dis_sprintf("%s", general_8bit_regname[reg]); }
// general purpose register or memory operand void disassembler::Eb(const x86_insn *insn) { if (insn->mod == 3) { if (insn->rm < 4 || insn->extend8b) dis_sprintf("%s", general_8bit_regname_rex[insn->rm]); else dis_sprintf("%s", general_8bit_regname[insn->rm]); } else (this->*resolve_modrm)(insn, B_SIZE); }
void disassembler::IwIb(const x86_insn *insn) { Bit16u iw = fetch_word(); Bit8u ib = fetch_byte(); if (intel_mode) { dis_sprintf("0x%04x, 0x%02x", iw, ib); } else { dis_sprintf("$0x%02x, $0x%04x", ib, iw); } }
void disassembler::IbIb(const x86_insn *insn) { Bit8u ib1 = fetch_byte(); Bit8u ib2 = fetch_byte(); if (intel_mode) { dis_sprintf("0x%02x, 0x%02x", ib1, ib2); } else { dis_sprintf("$0x%02x, $0x%02x", ib2, ib1); } }
void disassembler::Qq(const x86_insn *insn) { if (insn->mod == 3) { if (intel_mode) dis_sprintf ("mm%d", insn->rm & 0x7); else dis_sprintf("%%mm%d", insn->rm & 0x7); } else (this->*resolve_modrm)(insn, Q_SIZE); }
// jump offset void disassembler::Jb(const x86_insn *insn) { Bit8s imm8 = (Bit8s) fetch_byte(); if (insn->is_64) { Bit64u imm64 = (Bit8s) imm8; if (offset_mode_hex) { dis_sprintf(".+0x%08x%08x", GET32H(imm64), GET32L(imm64)); } else { dis_sprintf(".%+d", (int) imm8); } if (db_cs_base != BX_JUMP_TARGET_NOT_REQ) { Bit64u target = db_eip + imm64; target += db_cs_base; dis_sprintf(" (0x%08x%08x)", GET32H(target), GET32L(target)); } return; } if (insn->os_32) { Bit32u imm32 = (Bit8s) imm8; if (offset_mode_hex) { dis_sprintf(".+0x%08x", (unsigned) imm32); } else { dis_sprintf(".%+d", (int) imm8); } if (db_cs_base != BX_JUMP_TARGET_NOT_REQ) { Bit32u target = (Bit32u)(db_cs_base + db_eip + (Bit32s) imm32); dis_sprintf(" (0x%08x)", target); } } else { Bit16u imm16 = (Bit8s) imm8; if (offset_mode_hex) { dis_sprintf(".+0x%04x", (unsigned) imm16); } else { dis_sprintf(".%+d", (int) imm8); } if (db_cs_base != BX_JUMP_TARGET_NOT_REQ) { Bit16u target = (Bit16u)((db_eip + (Bit16s) imm16) & 0xffff); dis_sprintf(" (0x%08x)", target + db_cs_base); } } }
// gather VSib void disassembler::VSib(const x86_insn *insn) { if(insn->mod == 3) dis_sprintf("(bad)"); else (this->*resolve_modrm)(insn, (XMM_SIZE + insn->vex_l) | VSIB_Index); }
void disassembler::Ewd(const x86_insn *insn) { if (insn->mod == 3) dis_sprintf("%s", general_32bit_regname[insn->rm]); else (this->*resolve_modrm)(insn, W_SIZE); }
// memory operand void disassembler::OP_M(const x86_insn *insn, unsigned size) { if(insn->mod == 3) dis_sprintf("(bad)"); else (this->*resolve_modrm)(insn, size); }
void disassembler::Iq(const x86_insn *insn) { Bit64u value = fetch_qword(); if (! intel_mode) dis_putc('$'); dis_sprintf("0x%08x%08x", GET32H(value), GET32L(value)); }
void disassembler::print_disassembly_att(const x86_insn *insn, const BxDisasmOpcodeInfo_t *entry) { // print opcode dis_sprintf("%s ", entry->AttOpcode); if (entry->Operand3) { (this->*entry->Operand3)(insn); dis_sprintf(", "); } if (entry->Operand2) { (this->*entry->Operand2)(insn); dis_sprintf(", "); } if (entry->Operand1) { (this->*entry->Operand1)(insn); } }
void disassembler::Jw(const x86_insn *insn) { // Jw supported in 16-bit mode only assert(! insn->is_64); Bit16s imm16 = (Bit16s) fetch_word(); if (offset_mode_hex) { dis_sprintf(".+0x%04x", (unsigned) (Bit16u) imm16); } else { dis_sprintf(".%+d", (int) imm16); } if (db_cs_base != BX_JUMP_TARGET_NOT_REQ) { Bit16u target = (db_eip + imm16) & 0xffff; dis_sprintf(" (0x%08x)", target + db_cs_base); } }
void disassembler::OP_Y(const x86_insn *insn, unsigned size) { const char *rdi; if (insn->as_64) { rdi = general_64bit_regname[rDI_REG]; } else { if (insn->as_32) rdi = general_32bit_regname[rDI_REG]; else rdi = general_16bit_regname[rDI_REG]; } print_datasize(size); if (intel_mode) dis_sprintf("%s:[%s]", segment_name[ES_REG], rdi); else dis_sprintf("%s:(%s)", segment_name[ES_REG], rdi); }
void disassembler::Jd(const x86_insn *insn) { Bit32s imm32 = (Bit32s) fetch_dword(); if (insn->is_64) { Bit64u imm64 = (Bit32s) imm32; if (offset_mode_hex) { dis_sprintf(".+0x%08x%08x", GET32H(imm64), GET32L(imm64)); } else { dis_sprintf(".%+d", (int) imm32); } if (db_cs_base != BX_JUMP_TARGET_NOT_REQ) { Bit64u target = db_cs_base + db_eip + (Bit64s) imm64; dis_sprintf(" (0x%08x%08x)", GET32H(target), GET32L(target)); } return; } if (offset_mode_hex) { dis_sprintf(".+0x%08x", (unsigned) imm32); } else { dis_sprintf(".%+d", (int) imm32); } if (db_cs_base != BX_JUMP_TARGET_NOT_REQ) { Bit32u target = (Bit32u)(db_cs_base + db_eip + (Bit32s) imm32); dis_sprintf(" (0x%08x)", target); } }
void disassembler::print_memory_access16(int datasize, const char *seg, const char *index, uint16 disp) { print_datasize(datasize); if (intel_mode) { if (index == NULL) { dis_sprintf("%s:0x%x", seg, (unsigned) disp); } else { if (disp != 0) dis_sprintf("%s:[%s+0x%x]", seg, index, (unsigned) disp); else dis_sprintf("%s:[%s]", seg, index); } } else { if (index == NULL) { dis_sprintf("%s:0x%x", seg, (unsigned) disp); } else { if (disp != 0) dis_sprintf("%s:0x%x(%s,1)", seg, (unsigned) disp, index); else dis_sprintf("%s:(%s,1)", seg, index); } } }
void disassembler::print_datasize(unsigned size) { if (!intel_mode) return; switch(size) { case B_SIZE: dis_sprintf("byte ptr "); break; case W_SIZE: dis_sprintf("word ptr "); break; case D_SIZE: dis_sprintf("dword ptr "); break; case Q_SIZE: dis_sprintf("qword ptr "); break; case O_SIZE: dis_sprintf("dqword ptr "); break; case T_SIZE: dis_sprintf("tbyte ptr "); break; case P_SIZE: break; case X_SIZE: break; }; }
// direct memory access void disassembler::OP_O(const x86_insn *insn, unsigned size) { const char *seg; if (insn->is_seg_override()) seg = segment_name[insn->seg_override]; else seg = segment_name[DS_REG]; print_datasize(size); if (insn->as_64) { Bit64u imm64 = fetch_qword(); dis_sprintf("%s:0x%08x%08x", seg, GET32H(imm64), GET32L(imm64)); } else if (insn->as_32) { Bit32u imm32 = fetch_dword(); dis_sprintf("%s:0x%08x", seg, (unsigned) imm32); } else { Bit16u imm16 = fetch_word(); dis_sprintf("%s:0x%04x", seg, (unsigned) imm16); } }
void disassembler::VIb(const x86_insn *insn) { unsigned vreg = fetch_byte() >> 4; if (! insn->is_64) vreg &= 7; dis_sprintf("%s%d", vector_reg_name[insn->vex_l], vreg); }
void disassembler::Sw(const x86_insn *insn) { dis_sprintf("%s", segment_name[insn->nnn]); }
void disassembler::GS(const x86_insn *insn) { dis_sprintf("%s", segment_name[GS_REG]); }
void disassembler::RCX_Reg(const x86_insn *insn) { dis_sprintf("%s", general_64bit_regname[rCX_REG]); }
// 32-bit general purpose registers void disassembler::EAX_Reg(const x86_insn *insn) { dis_sprintf("%s", general_32bit_regname[rAX_REG]); }
void disassembler::Hdq(const x86_insn *insn) { dis_sprintf("%s%d", vector_reg_name[insn->vex_l], insn->vex_vvv); }