📄 disasm.cpp
字号:
WORD PeekW(PBYTE codebuf)
{
return *(WORD *)codebuf;
}
DWORD PeekD(PBYTE codebuf)
{
return *(DWORD *)codebuf;
}
BYTE CDisasm::GetByte()
{
return *(UasmCode+CodeCount);
}
WORD CDisasm::GetWord()
{
return *(WORD*)(UasmCode+CodeCount);
}
DWORD CDisasm::GetDWord()
{
return *(DWORD*)(UasmCode+CodeCount);
}
BYTE CDisasm::GetByteEx()
{
BYTE v = *(UasmCode+CodeCount);
CodeCount++;
return v;
}
WORD CDisasm::GetWordEx()
{
WORD v = *(WORD*)(UasmCode+CodeCount);
CodeCount+=2;
return v;
}
DWORD CDisasm::GetDWordEx()
{
DWORD v = *(DWORD*)(UasmCode+CodeCount);
CodeCount+=4;
return v;
}
/***********************************************************/
void CDisasm::SetError(DWORD errcode)
{
U_ErrorCode = errcode;
}
/***********************************************************/
// Global Function
// Set all of the field(s) of OPERITEM except **RWFLAG** and **SEG_INDEX**
BYTE CDisasm::Global_GetSize(DWORD srcsize)
{
switch(srcsize)
{
case SIZE_B:
return 1;
case SIZE_V:
if (OpSize == BIT16)
return 2;
else
return 4;
case SIZE_W:
return 2;
case SIZE_D:
return 4;
case SIZE_A:
return 8;
case SIZE_P:
if (U_Size == BIT16)
return 4;
else if (OpSize == BIT16)
return 4;
else
return 6;
}
return 0;
}
DWORD Global_SIB(PSTR outbuf,PBYTE codebuf,POPERITEM op,DWORD mod)
{
SIB sib;
sib.v=PeekB(codebuf);
char buf[128];
op->addr.base_reg_index=sib.base;
op->addr.off_reg_index=sib.index;
if (sib.ss==0)
op->addr.off_reg_scale=1;
else if (sib.ss==1)
op->addr.off_reg_scale=2;
else if (sib.ss==2)
op->addr.off_reg_scale=4;
else
op->addr.off_reg_scale=8;
// I have some mistakes! The manual say if index equal 4 there are no any scale register,
// but I understood that's invalid code at first.
if (sib.index == 4)
{
op->addr.off_reg_index = _NOREG_;
op->addr.off_reg_scale = 0;
if (sib.base == 5 && mod == 0)
{
op->addr.base_reg_index = _NOREG_;
op->addr.off_value = PeekD(codebuf + 1);
sprintf(buf, "[%08X]", op->addr.off_value);
return 5;
}
sprintf(buf, "%s", RegDWord[sib.base]);
}
else
{
if (sib.base == 5 && mod == 0)
{
op->addr.base_reg_index = _NOREG_;
op->addr.off_value = PeekD(codebuf + 1);
sprintf(outbuf, "[%s*%d+%08X]",
RegDWord[op->addr.off_reg_index],
op->addr.off_reg_scale,
op->addr.off_value
);
return 5;
}
sprintf(buf,"%s+%s*%d",
RegDWord[sib.base],
RegDWord[sib.index],
op->addr.off_reg_scale
);
}
if (mod == 1)
{
op->addr.off_value=PeekB(codebuf+1);
sprintf(outbuf,"[%s+%02X]",buf,op->addr.off_value);
return 2;
}
else if (mod == 2)
{ //Now mod is 2
op->addr.off_value=PeekD(codebuf+1);
sprintf(outbuf,"[%s+%08X]",buf,op->addr.off_value);
return 5;
}
else
{
sprintf(outbuf,"[%s]",buf);
return 1;
}
}
DWORD CDisasm::Global_MEMORY(PSTR outbuf,PBYTE codebuf,POPERITEM op)
{
MODRM modrm;
DWORD len=1;
//BYTE by;
//WORD wo;
//DWORD dw;
modrm.v = PeekB(codebuf);
if( AdrSize==BIT32 )
{
op->mode = OP_Address;
//op->addr.reg_size=sizeof(DWORD);
op->addr.base_reg_index=modrm.rm;
op->addr.off_reg_index=_NOREG_;
op->addr.off_reg_scale=1;
op->addr.off_value=0;
if (modrm.rm==4)
return Global_SIB(outbuf,codebuf+1,op,modrm.mod)+len;
if (modrm.rm==5&&modrm.mod==0)
{
op->addr.base_reg_index=_NOREG_;
op->addr.off_value=PeekD(codebuf+1);
sprintf(outbuf,"[%08X]",op->addr.off_value);
len+=4;
return len;
}
if (modrm.mod==0)
{
sprintf(outbuf,"[%s]",RegDWord[modrm.rm]);
}
else if (modrm.mod==1)
{
signed char signoffset = (signed char)PeekB(codebuf+1);
op->addr.off_value=(DWORD)(signed int)signoffset;
if (signoffset < 0)
sprintf(outbuf,"[%s-%02X]",RegDWord[modrm.rm],-signoffset);
else
sprintf(outbuf,"[%s+%02X]",RegDWord[modrm.rm],signoffset);
len+=1;
}
else
{ //mod is 2
op->addr.off_value=PeekD(codebuf+1);
sprintf(outbuf,"[%s+%08X]",RegDWord[modrm.rm],op->addr.off_value);
len+=4;
}
}
else
{
op->mode = OP_Address;
//op->addr.reg_size=sizeof(WORD);
op->addr.base_reg_index=_NOREG_;
op->addr.off_reg_index=_NOREG_;
op->addr.off_reg_scale=1;
op->addr.off_value=0;
if (modrm.rm==6&&modrm.mod==0)
{
op->addr.off_value=PeekW(codebuf+1);
sprintf(outbuf,"[%04X]",op->addr.off_value);
len+=2;
return len;
}
char *reg16off;
switch(modrm.rm)
{
case 0:
op->addr.base_reg_index=_BX_;
op->addr.off_reg_index=_SI_;
reg16off="BX+SI";
break;
case 1:
op->addr.base_reg_index=_BX_;
op->addr.off_reg_index=_DI_;
reg16off="BX+DI";
break;
case 2:
op->addr.base_reg_index=_BP_;
op->addr.off_reg_index=_SI_;
reg16off="BP+SI";
break;
case 3:
op->addr.base_reg_index=_BP_;
op->addr.off_reg_index=_DI_;
reg16off="BP+DI";
break;
case 4:
op->addr.base_reg_index=_SI_;
reg16off="SI";
break;
case 5:
op->addr.base_reg_index=_DI_;
reg16off="DI";
break;
case 6:
op->addr.base_reg_index=_BP_;
reg16off="BP";
break;
case 7:
op->addr.base_reg_index=_BX_;
reg16off="BX";
}
if (modrm.mod==0)
{
sprintf(outbuf,"[%s]",reg16off);
}
else if (modrm.mod==1)
{
signed char signoffset = (signed char)PeekB(codebuf+1);
op->addr.off_value=(DWORD)(signed int)signoffset;
if (signoffset < 0)
sprintf(outbuf,"[%s-%02X]",reg16off,-signoffset);
else
sprintf(outbuf,"[%s+%02X]",reg16off,signoffset);
len+=1;
}
else
{ //mod is 2
op->addr.off_value=PeekW(codebuf+1);
sprintf(outbuf,"[%s+%04X]",reg16off,op->addr.off_value);
len+=2;
}
}
return len;
}
DWORD CDisasm::Global_MODRM(PSTR outbuf,PBYTE codebuf,POPERITEM op)
{
MODRM modrm;
modrm.v = PeekB(codebuf);
if (modrm.mod==3)
{
op->mode = OP_Register;
if (op->opersize == 1)
{
strcpy(outbuf,RegByte[modrm.rm]);
}
else if (op->opersize == 2)
{
strcpy(outbuf,RegWord[modrm.rm]);
}
else
{
strcpy(outbuf,RegDWord[modrm.rm]);
}
op->reg.reg_index=modrm.rm;
return 1;
}
return Global_MEMORY(outbuf,codebuf,op);
}
DWORD CDisasm::Global_OFFSET(PSTR outbuf,PBYTE codebuf,POPERITEM op)
{
op->mode=OP_Address;
//op->addr.reg_size = 0;
op->addr.base_reg_index = _NOREG_;
op->addr.off_reg_index = _NOREG_;
op->addr.off_reg_scale = 0;
if (AdrSize == BIT16)
{
op->addr.off_value = PeekW(codebuf);
sprintf(outbuf,"[%04X]",op->addr.off_value);
return sizeof(WORD);
}
else
{
op->addr.off_value = PeekW(codebuf);
sprintf(outbuf,"[%08X]",op->addr.off_value);
return sizeof(DWORD);
}
}
DWORD Global_REG(PSTR outbuf,PBYTE codebuf,POPERITEM op)
{
MODRM modrm;
modrm.v=PeekB(codebuf);
op->mode = OP_Register;
if (op->opersize == 1)
{
strcpy(outbuf,RegByte[modrm.reg]);
}
else if (op->opersize == 2)
{
strcpy(outbuf,RegWord[modrm.reg]);
}
else
{
strcpy(outbuf,RegDWord[modrm.reg]);
}
op->reg.reg_index=modrm.reg;
return 0;
}
DWORD Global_SREG(PSTR outbuf,PBYTE codebuf,POPERITEM op)
{
MODRM modrm;
modrm.v = PeekB(codebuf);
op->mode = OP_Segment;
strcpy(outbuf,SegReg[modrm.reg]);
op->sreg.sreg_index=modrm.reg;
return 0;
}
DWORD Global_IMMED(PSTR outbuf,PBYTE codebuf,POPERITEM op)
{
op->mode = OP_Immed;
if (op->opersize == 1)
{
op->immed.immed_value=(DWORD)(int)(signed char)PeekB(codebuf);
sprintf(outbuf,"%02X",(BYTE)op->immed.immed_value);
}
else if (op->opersize == 2)
{
op->immed.immed_value=PeekW(codebuf);
sprintf(outbuf,"%04X",op->immed.immed_value);
}
else
{
op->immed.immed_value=PeekD(codebuf);
sprintf(outbuf,"%08X",op->immed.immed_value);
}
return op->opersize;
}
DWORD Global_SIGNEDIMMED(PSTR outbuf,PBYTE codebuf,POPERITEM op)
{
op->mode = OP_Immed;
signed char by = (signed char)PeekB(codebuf);
if (by < 0)
sprintf(outbuf,"-%02X",-by);
else
sprintf(outbuf,"+%02X",by);
op->immed.immed_value=(DWORD)(int)by;
return 1;
}
DWORD CDisasm::Global_NEARPTR(PSTR outbuf,PBYTE codebuf,POPERITEM op)
{
op->mode = OP_Near;
if (op->opersize == 1)
{
op->nearptr.offset = BaseAddress + CodeCount + 1 + (int)(char)PeekB(codebuf);
}
else if (op->opersize == 2)
{
op->nearptr.offset = BaseAddress + CodeCount + 2 + (int)(short)PeekW(codebuf);
}
else
{
op->nearptr.offset = BaseAddress + CodeCount + 4 + (int)PeekD(codebuf);
}
if (U_Size == BIT16)
sprintf(outbuf,"%04X",op->nearptr.offset);
else
sprintf(outbuf,"%08X",op->nearptr.offset);
return op->opersize;
}
DWORD CDisasm::Global_FARPTR(PSTR outbuf,PBYTE codebuf,POPERITEM op)
{
op->mode = OP_Far;
if (op->opersize == 4)
{
op->farptr.offset = PeekW(codebuf);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -