fc1473cb8c
dos2unix cleanup
375 lines
8.3 KiB
C++
Executable File
375 lines
8.3 KiB
C++
Executable File
#include "disasm.h"
|
|
|
|
extern const char *general_16bit_reg_name[8];
|
|
extern const char *general_32bit_reg_name[8];
|
|
|
|
static const char *sreg_mod01_rm32[8] = {
|
|
"ds", "ds", "ds", "ds", "??", "ss", "ds", "ds"
|
|
};
|
|
|
|
static const char *sreg_mod10_rm32[8] = {
|
|
"ds", "ds", "ds", "ds", "??", "ss", "ds", "ds"
|
|
};
|
|
|
|
static const char *sreg_mod00_base32[8] = {
|
|
"ds", "ds", "ds", "ds", "ss", "ds", "ds", "ds"
|
|
};
|
|
|
|
static const char *sreg_mod01_base32[8] = {
|
|
"ds", "ds", "ds", "ds", "ss", "ss", "ds", "ds"
|
|
};
|
|
|
|
static const char *sreg_mod10_base32[8] = {
|
|
"ds", "ds", "ds", "ds", "ss", "ss", "ds", "ds"
|
|
};
|
|
|
|
static const char *sreg_mod00_rm16[8] = {
|
|
"ds", "ds", "ss", "ss", "ds", "ds", "ds", "ds"
|
|
};
|
|
|
|
static const char *sreg_mod01_rm16[8] = {
|
|
"ds", "ds", "ss", "ss", "ds", "ds", "ss", "ds"
|
|
};
|
|
|
|
static const char *sreg_mod10_rm16[8] = {
|
|
"ds", "ds", "ss", "ss", "ds", "ds", "ss", "ds"
|
|
};
|
|
|
|
static const char *intel_index16[8] = {
|
|
"bx+si",
|
|
"bx+di",
|
|
"bp+si",
|
|
"bp+di",
|
|
"si",
|
|
"di",
|
|
"bp",
|
|
"bx"
|
|
};
|
|
|
|
static const char *index_name32[8] = {
|
|
"eax", "ecx", "edx", "ebx", "???", "ebp", "esi", "edi"
|
|
};
|
|
|
|
void disassembler::decode_modrm()
|
|
{
|
|
modrm = fetch_byte();
|
|
BX_DECODE_MODRM(modrm, mod, nnn, rm);
|
|
|
|
if (i32bit_addrsize)
|
|
{
|
|
/* use 32bit addressing modes. orthogonal base & index registers,
|
|
scaling available, etc. */
|
|
if (mod == 3) {
|
|
/* mod, reg, reg */
|
|
return;
|
|
}
|
|
else { /* mod != 3 */
|
|
if (rm != 4) { /* rm != 100b, no s-i-b byte */
|
|
// one byte modrm
|
|
switch (mod) {
|
|
case 0:
|
|
resolve_modrm = &disassembler::resolve32_mod0;
|
|
if (rm == 5) /* no reg, 32-bit displacement */
|
|
displacement.displ32 = fetch_dword();
|
|
break;
|
|
case 1:
|
|
/* reg, 8-bit displacement, sign extend */
|
|
resolve_modrm = &disassembler::resolve32_mod1;
|
|
displacement.displ32 = (Bit8s) fetch_byte();
|
|
break;
|
|
case 2:
|
|
/* reg, 32-bit displacement */
|
|
resolve_modrm = &disassembler::resolve32_mod2;
|
|
displacement.displ32 = fetch_dword();
|
|
break;
|
|
} /* switch (mod) */
|
|
} /* if (rm != 4) */
|
|
else { /* rm == 4, s-i-b byte follows */
|
|
sib = fetch_byte();
|
|
BX_DECODE_SIB(sib, scale, index, base);
|
|
|
|
switch (mod) {
|
|
case 0:
|
|
resolve_modrm = &disassembler::resolve32_mod0_rm4;
|
|
if (base == 5)
|
|
displacement.displ32 = fetch_dword();
|
|
break;
|
|
case 1:
|
|
resolve_modrm = &disassembler::resolve32_mod1_rm4;
|
|
displacement.displ8 = fetch_byte();
|
|
break;
|
|
case 2:
|
|
resolve_modrm = &disassembler::resolve32_mod2_rm4;
|
|
displacement.displ32 = fetch_dword();
|
|
break;
|
|
}
|
|
} /* s-i-b byte follows */
|
|
} /* if (mod != 3) */
|
|
}
|
|
else {
|
|
/* 16 bit addressing modes. */
|
|
switch (mod) {
|
|
case 0:
|
|
resolve_modrm = &disassembler::resolve16_mod0;
|
|
if(rm == 6)
|
|
displacement.displ16 = fetch_word();
|
|
break;
|
|
case 1:
|
|
/* reg, 8-bit displacement, sign extend */
|
|
resolve_modrm = &disassembler::resolve16_mod1;
|
|
displacement.displ16 = (Bit8s) fetch_byte();
|
|
break;
|
|
case 2:
|
|
resolve_modrm = &disassembler::resolve16_mod2;
|
|
displacement.displ16 = fetch_word();
|
|
break;
|
|
case 3:
|
|
/* mod, reg, reg */
|
|
return;
|
|
|
|
} /* switch (mod) ... */
|
|
}
|
|
}
|
|
|
|
void disassembler::print_datasize(unsigned mode)
|
|
{
|
|
switch(mode)
|
|
{
|
|
case B_MODE:
|
|
dis_sprintf("byte ptr ");
|
|
break;
|
|
case W_MODE:
|
|
dis_sprintf("word ptr ");
|
|
break;
|
|
case D_MODE:
|
|
dis_sprintf("dword ptr ");
|
|
break;
|
|
case V_MODE:
|
|
if (i32bit_opsize)
|
|
dis_sprintf("dword ptr ");
|
|
else
|
|
dis_sprintf("word ptr ");
|
|
break;
|
|
case Q_MODE:
|
|
dis_sprintf("qword ptr ");
|
|
break;
|
|
case O_MODE:
|
|
dis_sprintf("oword ptr ");
|
|
break;
|
|
case T_MODE:
|
|
dis_sprintf("tword ptr ");
|
|
break;
|
|
case X_MODE:
|
|
break;
|
|
};
|
|
}
|
|
|
|
void disassembler::resolve16_mod0(unsigned mode)
|
|
{
|
|
const char *mod_rm_seg_reg;
|
|
|
|
if (seg_override)
|
|
mod_rm_seg_reg = seg_override;
|
|
else
|
|
mod_rm_seg_reg = sreg_mod00_rm16[rm];
|
|
|
|
print_datasize(mode);
|
|
|
|
if(rm == 6)
|
|
{
|
|
dis_sprintf("[%s:0x%x]", mod_rm_seg_reg, (unsigned) displacement.displ16);
|
|
}
|
|
else
|
|
{
|
|
dis_sprintf("%s:[%s]", mod_rm_seg_reg, intel_index16[rm]);
|
|
}
|
|
}
|
|
|
|
void disassembler::resolve16_mod1(unsigned mode)
|
|
{
|
|
const char *mod_rm_seg_reg;
|
|
|
|
if (seg_override)
|
|
mod_rm_seg_reg = seg_override;
|
|
else
|
|
mod_rm_seg_reg = sreg_mod01_rm16[rm];
|
|
|
|
print_datasize(mode);
|
|
|
|
if (displacement.displ16)
|
|
{
|
|
dis_sprintf("%s:[%s+0x%x]", mod_rm_seg_reg,
|
|
intel_index16[rm], (unsigned) displacement.displ16);
|
|
}
|
|
else
|
|
{
|
|
dis_sprintf("%s:[%s]", mod_rm_seg_reg, intel_index16[rm]);
|
|
}
|
|
}
|
|
|
|
void disassembler::resolve16_mod2(unsigned mode)
|
|
{
|
|
const char *mod_rm_seg_reg;
|
|
|
|
if (seg_override)
|
|
mod_rm_seg_reg = seg_override;
|
|
else
|
|
mod_rm_seg_reg = sreg_mod10_rm16[rm];
|
|
|
|
print_datasize(mode);
|
|
|
|
if (displacement.displ16)
|
|
{
|
|
dis_sprintf("%s:[%s+0x%x]", mod_rm_seg_reg,
|
|
intel_index16[rm], (unsigned) displacement.displ16);
|
|
}
|
|
else
|
|
{
|
|
dis_sprintf("%s:[%s]", mod_rm_seg_reg, intel_index16[rm]);
|
|
}
|
|
}
|
|
|
|
void disassembler::resolve32_mod0(unsigned mode)
|
|
{
|
|
const char *mod_rm_seg_reg;
|
|
|
|
if (seg_override)
|
|
mod_rm_seg_reg = seg_override;
|
|
else
|
|
mod_rm_seg_reg = "ds";
|
|
|
|
print_datasize(mode);
|
|
|
|
if (rm == 5) { /* no reg, 32-bit displacement */
|
|
dis_sprintf("[%s:0x%x]", mod_rm_seg_reg, displacement.displ32);
|
|
}
|
|
else {
|
|
dis_sprintf("%s:[%s]", mod_rm_seg_reg, general_32bit_reg_name[rm]);
|
|
}
|
|
}
|
|
|
|
void disassembler::resolve32_mod1(unsigned mode)
|
|
{
|
|
const char *mod_rm_seg_reg;
|
|
|
|
if (seg_override)
|
|
mod_rm_seg_reg = seg_override;
|
|
else
|
|
mod_rm_seg_reg = sreg_mod01_rm32[rm];
|
|
|
|
print_datasize(mode);
|
|
|
|
/* reg, 8-bit displacement, sign extend */
|
|
if (displacement.displ32)
|
|
{
|
|
dis_sprintf("%s:[%s+0x%x]", mod_rm_seg_reg,
|
|
general_32bit_reg_name[rm], (unsigned) displacement.displ32);
|
|
}
|
|
else
|
|
{
|
|
dis_sprintf("%s:[%s]", mod_rm_seg_reg, general_32bit_reg_name[rm]);
|
|
}
|
|
}
|
|
|
|
void disassembler::resolve32_mod2(unsigned mode)
|
|
{
|
|
const char *mod_rm_seg_reg;
|
|
|
|
if (seg_override)
|
|
mod_rm_seg_reg = seg_override;
|
|
else
|
|
mod_rm_seg_reg = sreg_mod10_rm32[rm];
|
|
|
|
print_datasize(mode);
|
|
|
|
/* reg, 32-bit displacement */
|
|
if (displacement.displ32)
|
|
{
|
|
dis_sprintf("%s:[%s+0x%x]", mod_rm_seg_reg,
|
|
general_32bit_reg_name[rm], (unsigned) displacement.displ32);
|
|
}
|
|
else
|
|
{
|
|
dis_sprintf("%s:[%s]", mod_rm_seg_reg, general_32bit_reg_name[rm]);
|
|
}
|
|
}
|
|
|
|
void disassembler::resolve32_mod0_rm4(unsigned mode)
|
|
{
|
|
const char *mod_rm_seg_reg;
|
|
|
|
if (seg_override)
|
|
mod_rm_seg_reg = seg_override;
|
|
else
|
|
mod_rm_seg_reg = sreg_mod00_base32[base];
|
|
|
|
print_datasize(mode);
|
|
|
|
dis_sprintf("%s:[", mod_rm_seg_reg);
|
|
if (base != 5)
|
|
dis_sprintf("%s+", general_32bit_reg_name[base]);
|
|
|
|
if (index != 4)
|
|
{
|
|
dis_sprintf("%s", index_name32[index]);
|
|
if (scale)
|
|
dis_sprintf("*%u", 1 << scale);
|
|
if (base == 5) dis_sprintf("+");
|
|
}
|
|
|
|
if (base == 5)
|
|
dis_sprintf("0x%x", (unsigned) displacement.displ32);
|
|
|
|
dis_sprintf("]");
|
|
}
|
|
|
|
void disassembler::resolve32_mod1_rm4(unsigned mode)
|
|
{
|
|
const char *mod_rm_seg_reg;
|
|
if (seg_override)
|
|
mod_rm_seg_reg = seg_override;
|
|
else
|
|
mod_rm_seg_reg = sreg_mod01_base32[base];
|
|
|
|
print_datasize(mode);
|
|
|
|
dis_sprintf("%s:[%s", mod_rm_seg_reg, general_32bit_reg_name[base]);
|
|
|
|
if (index != 4)
|
|
{
|
|
dis_sprintf("+%s", index_name32[index]);
|
|
if (scale)
|
|
dis_sprintf("*%u", 1 << scale);
|
|
}
|
|
|
|
if (displacement.displ8)
|
|
dis_sprintf("+0x%x", (unsigned) displacement.displ8);
|
|
|
|
dis_sprintf("]");
|
|
}
|
|
|
|
void disassembler::resolve32_mod2_rm4(unsigned mode)
|
|
{
|
|
const char *mod_rm_seg_reg;
|
|
if (seg_override)
|
|
mod_rm_seg_reg = seg_override;
|
|
else
|
|
mod_rm_seg_reg = sreg_mod10_base32[base];
|
|
|
|
print_datasize(mode);
|
|
|
|
dis_sprintf("%s:[%s", mod_rm_seg_reg, general_32bit_reg_name[base]);
|
|
|
|
if (index != 4)
|
|
{
|
|
dis_sprintf("+%s", index_name32[index]);
|
|
if (scale)
|
|
dis_sprintf("*%u", 1 << scale);
|
|
}
|
|
|
|
if (displacement.displ32)
|
|
dis_sprintf("+0x%x", (unsigned) displacement.displ32);
|
|
|
|
dis_sprintf("]");
|
|
}
|