📄 disasm.cpp
字号:
cbyte=ibuff[0];
if(tabtype==TABLE_EXT)
cbyte=ibuff[1];
if(tabtype==TABLE_EXT2)
cbyte=ibuff[2];
if((tabtype==TABLE_EXT2)&&(options.processor==PROC_Z80))
cbyte=ibuff[3];
while(itable[tablenum].table!=NULL) // search tables
{ righttable=true;
if((itable[tablenum].type!=tabtype)||(itable[tablenum].minlim>cbyte)||
(itable[tablenum].maxlim<cbyte)) righttable=false;
if(((tabtype==TABLE_EXT)||(tabtype==TABLE_EXT2))&&(ibuff[0]!=itable[tablenum].extnum))
righttable=false;
if((tabtype==TABLE_EXT2)&&(ibuff[1]!=itable[tablenum].extnum2))
righttable=false;
if(righttable)
{ insttab=itable[tablenum].table; // need to search this now
instnum=0;
mbyte=cbyte;
fupbyte=false;
if(itable[tablenum].divisor)
mbyte=(byte)(mbyte/itable[tablenum].divisor);
if(itable[tablenum].mask)
mbyte=mbyte&itable[tablenum].mask;
else // follow up byte encodings (KNI,AMD3DNOW)
{ fupbyte=true;
flgs=insttab[instnum].flags;
a1=insttab[instnum].arg1;
a2=insttab[instnum].arg2;
a3=insttab[instnum].arg3;
#ifdef __BORLANDC__
#pragma warn -sig
#endif
length=1+arglength(a1,mcode[1+itable[tablenum].modrmpos],mcode[2+itable[tablenum].modrmpos],flgs,true)
+arglength(a2,mcode[1+itable[tablenum].modrmpos],mcode[2+itable[tablenum].modrmpos],flgs,true)
+arglength(a3,mcode[1+itable[tablenum].modrmpos],mcode[2+itable[tablenum].modrmpos],flgs,true)
+itable[tablenum].modrmpos;
#ifdef __BORLANDC__
#pragma warn +sig
#endif
// addition for table extensions where inst is part of modrm byte
if(((tabtype==TABLE_EXT)||(tabtype==TABLE_EXT2))&&(length==1))
length++;
mbyte=ibuff[length];
}
while((insttab[instnum].name!=NULL)||(insttab[instnum].instbyte)||(insttab[instnum].processor))
{ if((omode32)&&(insttab[instnum].flags&FLAGS_OMODE16));
else if((!omode32)&&(insttab[instnum].flags&FLAGS_OMODE32));
else if((insttab[instnum].instbyte==mbyte)&&(insttab[instnum].processor&options.processor))
{ // found it
if(insttab[instnum].name==NULL)
{ if(tabtype==TABLE_MAIN)
return decodeinst(ibuff,mcode,loc,TABLE_EXT,omode32,5);
else
return decodeinst(ibuff,mcode,loc,TABLE_EXT2,omode32,5);
}
else
{ // interpret flags,etc
flgs=insttab[instnum].flags;
if((flgs&FLAGS_OPERPREFIX)&&(depth<5))
{ newdsm=decodeinst(ibuff+1,mcode+1,loc+1,tabtype,!omode32,depth+1);
if(newdsm==NULL)
return NULL;
newdsm->addr.offs--;
newdsm->length++;
newdsm->modrm++;
newdsm->data--;
return newdsm;
}
if((flgs&FLAGS_ADDRPREFIX)&&(depth<5))
{ options.mode32=!options.mode32;
options.mode16=!options.mode16;
newdsm=decodeinst(ibuff+1,mcode+1,loc+1,tabtype,omode32,depth+1);
options.mode32=!options.mode32;
options.mode16=!options.mode16;
if(newdsm==NULL)
return NULL;
newdsm->addr.offs--;
newdsm->length++;
newdsm->modrm++;
newdsm->data--;
newdsm->flags=newdsm->flags|FLAGS_ADDRPREFIX;
return newdsm;
}
if((flgs&FLAGS_SEGPREFIX)&&(depth<5))
{ newdsm=decodeinst(ibuff+1,mcode+1,loc+1,tabtype,omode32,depth+1);
if(newdsm==NULL)
return NULL;
newdsm->addr.offs--;
newdsm->length++;
newdsm->modrm++;
newdsm->data--;
newdsm->flags=newdsm->flags|FLAGS_SEGPREFIX;
return newdsm;
}
if((flgs&FLAGS_PREFIX)&&(depth<5))
{ newdsm=decodeinst(ibuff+1,mcode+1,loc+1,tabtype,omode32,depth+1);
if(newdsm==NULL)
return NULL;
newdsm->addr.offs--;
newdsm->length++;
newdsm->modrm++;
newdsm->data--;
newdsm->flags=newdsm->flags|FLAGS_PREFIX;
return newdsm;
}
newdsm=new dsmitem;
initnewdsm(newdsm,loc,dsmcode);
newdsm->tptr=(void *)&insttab[instnum];
newdsm->modrm=(byte)(1+itable[tablenum].modrmpos);
newdsm->data=mcode;
newdsm->mode32=omode32;
if(flgs&FLAGS_16BIT)
newdsm->mode32=false;
if(flgs&FLAGS_32BIT)
newdsm->mode32=true;
newdsm->flags=flgs;
a1=insttab[instnum].arg1;
a2=insttab[instnum].arg2;
a3=insttab[instnum].arg3;
#ifdef __BORLANDC__
#pragma warn -sig
#endif
length=1+arglength(a1,mcode[1+itable[tablenum].modrmpos],mcode[2+itable[tablenum].modrmpos],flgs,newdsm->mode32)
+arglength(a2,mcode[1+itable[tablenum].modrmpos],mcode[2+itable[tablenum].modrmpos],flgs,newdsm->mode32)
+arglength(a3,mcode[1+itable[tablenum].modrmpos],mcode[2+itable[tablenum].modrmpos],flgs,newdsm->mode32)
+itable[tablenum].modrmpos;
#ifdef __BORLANDC__
#pragma warn +sig
#endif
// addition for table extensions where inst is part of modrm byte
if(((tabtype==TABLE_EXT)||(tabtype==TABLE_EXT2))&&((length==1)||(options.processor==PROC_Z80)))
length++;
if(options.processor==PROC_Z80)
{ if(tabtype==TABLE_EXT2)
length++;
if(flgs&FLAGS_INDEXREG)
length++;
}
if(fupbyte)
length++;
newdsm->length=length;
if(!checkvalid(newdsm))
{ delete newdsm;
return NULL;
}
if(flgs&(FLAGS_JMP|FLAGS_CALL|FLAGS_CJMP))
{ switch(a1)
{ case ARG_RELIMM:
j=loc;
dta=mcode+length;
if(options.mode32)
{ dta-=4;
j+=((dword *)dta)[0]+length;
}
else
{ dta-=2;
j+=(word)(((word *)dta)[0]+length);
}
scheduler.addtask(dis_code,priority_definitecode,j,NULL);
xrefs.addxref(j,newdsm->addr);
break;
case ARG_RELIMM8:
j=loc;
dta=mcode+length-1;
if(options.mode32)
{ if(dta[0]&0x80)
j+=(dword)(dta[0]+0xffffff00+length);
else
j+=(dword)(dta[0]+length);
}
else
{ if(dta[0]&0x80)
j+=(word)(dta[0]+0xff00+length);
else
j+=(word)(dta[0]+length);
}
scheduler.addtask(dis_code,priority_definitecode,j,NULL);
xrefs.addxref(j,newdsm->addr);
break;
case ARG_FADDR:
dta=mcode+length;
if(options.mode32)
{ dta-=6;
j.assign(((word *)(&dta[4]))[0],((dword *)(&dta[0]))[0]);
}
else
{ dta-=4;
j.assign(((word *)(&dta[2]))[0],((word *)(&dta[0]))[0]);
}
scheduler.addtask(dis_code,priority_definitecode,j,NULL);
xrefs.addxref(j,newdsm->addr);
break;
case ARG_MODRM:
case ARG_MODRM_FPTR:
if(options.mode32)
{ if((newdsm->data[0]==0xff)&&(newdsm->data[1]==0x25)&&(tabtype==TABLE_EXT))
{ j.assign(loc.segm,((dword *)(&newdsm->data[2]))[0]);
if(import.isname(j))
{ imp=import.nextiterator();
impname[0]='_';
impname[GNAME_MAXLEN]=0;
lstrcpyn(&impname[1],imp->name,GNAME_MAXLEN-2);
//if(!name.isname(segm,offs))
scheduler.addtask(namecurloc,priority_nameloc,loc,impname);
}
}
}
scheduler.addtask(dis_jumptable,priority_definitecode,loc,NULL);
break;
default:
break;
}
}
switch(a1)
{ case ARG_IMM32:
if(reloc.isreloc(loc+length-4))
{ newdsm->override=over_dsoffset;
dta=mcode+length-4;
j.assign(options.dseg,((dword *)(&dta[0]))[0]);
xrefs.addxref(j,newdsm->addr);
}
break;
case ARG_IMM:
if(options.mode32)
{ if(reloc.isreloc(loc+length-4))
{ newdsm->override=over_dsoffset;
dta=mcode+length-4;
j.assign(options.dseg,((dword *)(&dta[0]))[0]);
xrefs.addxref(j,newdsm->addr);
}
}
break;
case ARG_MEMLOC:
if(options.mode32)
{ newdsm->override=over_dsoffset;
dta=mcode+length-4;
j.assign(options.dseg,((dword *)(&dta[0]))[0]);
xrefs.addxref(j,newdsm->addr);
}
break;
case ARG_MMXMODRM:
case ARG_XMMMODRM:
case ARG_MODRM_S:
case ARG_MODRMM512:
case ARG_MODRMQ:
case ARG_MODRM_SREAL:
case ARG_MODRM_PTR:
case ARG_MODRM_WORD:
case ARG_MODRM_SINT:
case ARG_MODRM_EREAL:
case ARG_MODRM_DREAL:
case ARG_MODRM_WINT:
case ARG_MODRM_LINT:
case ARG_MODRM_BCD:
case ARG_MODRM_FPTR:
case ARG_MODRM:
if(options.mode32)
if((newdsm->data[newdsm->modrm]&0xc7)==5) // straight disp32
{ dta=mcode+newdsm->modrm+1;
j.assign(options.dseg,((dword *)(&dta[0]))[0]);
xrefs.addxref(j,newdsm->addr);
}
break;
default:
break;
}
switch(a2)
{ case ARG_IMM32:
if(reloc.isreloc(loc+length-4))
{ newdsm->override=over_dsoffset;
dta=mcode+length-4;
j.assign(options.dseg,((dword *)(&dta[0]))[0]);
xrefs.addxref(j,newdsm->addr);
}
break;
case ARG_IMM:
if(options.mode32)
{ if(reloc.isreloc(loc+length-4))
{ newdsm->override=over_dsoffset;
dta=mcode+length-4;
j.assign(options.dseg,((dword *)(&dta[0]))[0]);
xrefs.addxref(j,newdsm->addr);
}
}
break;
case ARG_MEMLOC:
if(options.mode32)
{ newdsm->override=over_dsoffset;
dta=mcode+length-4;
j.assign(options.dseg,((dword *)(&dta[0]))[0]);
xrefs.addxref(j,newdsm->addr);
}
break;
case ARG_MMXMODRM:
case ARG_XMMMODRM:
case ARG_MODRM_S:
case ARG_MODRMM512:
case ARG_MODRMQ:
case ARG_MODRM_SREAL:
case ARG_MODRM_PTR:
case ARG_MODRM_WORD:
case ARG_MODRM_SINT:
case ARG_MODRM_EREAL:
case ARG_MODRM_DREAL:
case ARG_MODRM_WINT:
case ARG_MODRM_LINT:
case ARG_MODRM_BCD:
case ARG_MODRM_FPTR:
case ARG_MODRM:
if(options.mode32)
if((newdsm->data[newdsm->modrm]&0xc7)==5) // straight disp32
{ dta=mcode+newdsm->modrm+1;
j.assign(options.dseg,((dword *)(&dta[0]))[0]);
xrefs.addxref(j,newdsm->addr);
}
break;
default:
break;
}
return newdsm;
}
}
instnum++;
}
}
tablenum++;
}
return NULL;
}
/************************************************************************
* arglength *
* - a function which returns the increase in length of an instruction *
* due to its argtype, used by the decodeinst engine in calculating *
* the instruction length *
************************************************************************/
byte disasm::arglength(argtype a,byte modrmbyte,byte sibbyte,dword flgs,bool omode32)
{ byte rm;
switch(a)
{ case ARG_IMM:
if(flgs&FLAGS_8BIT)
return 1;
if(!omode32)
return 2;
else
return 4;
case ARG_NONEBYTE:
return 1;
case ARG_RELIMM:
case ARG_MEMLOC:
if(options.mode16)
return 2;
else
return 4;
case ARG_RELIMM8:
case ARG_SIMM8:
case ARG_IMM8:
case ARG_IMM8_IND:
return 1;
case ARG_IMM32:
return 4;
case ARG_IMM16_A:
case ARG_IMM16:
case ARG_MEMLOC16:
return 2;
case ARG_FADDR:
if(options.mode16)
return 4;
else
return 6;
case ARG_MODREG:
case ARG_MMXMODRM:
case ARG_XMMMODRM:
case ARG_MODRM8:
case ARG_MODRM16:
case ARG_MODRM_S:
case ARG_MODRMM512:
case ARG_MODRMQ:
case ARG_MODRM_SREAL:
case ARG_MODRM_PTR:
case ARG_MODRM_WORD:
case ARG_MODRM_SINT:
case ARG_MODRM_EREAL:
case ARG_MODRM_DREAL:
case ARG_MODRM_WINT:
case ARG_MODRM_LINT:
case ARG_MODRM_BCD:
case ARG_MODRM_FPTR:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -