//					DISASM.CPP

#include <windows.h>
#include <commctrl.h>

#include "disasm.h"
#include "pefiles.h"
#include "textout.h"
#include "imports.h"
#include "exports.h"
#include "comments.h"
#include "reloc.h"
#include "dasm.h"
#include "opcodes.h"
#include "xref.h"

static char *regtable[]=
{ "error",
  "eax","ecx","edx","ebx","esp","ebp","esi","edi",
  "ax","cx","dx","bx","sp","bp","si","di",
  "al","cl","dl","bl","ah","ch","dh","bh",
  "es","cs","ss","ds","fs","gs","bx+si","bx+di","bp+si","bp+di",
  "cr0","error","cr2","cr3","cr4","error","error","error",
  "dr0","dr1","dr2","dr3","error","error","dr6","dr7",
  "error","error","error","tr3","tr4","tr5","tr6","tr7",
  "mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7"
};

static char *ftable[]=
{ "error",
  "st(0)","st(1)","st(2)","st(3)","st(4)","st(5)","st(6)","st(7)"
};

static char *jtable[]=
{ "jo","jno","jc","jnc","jz","jnz","jbe","ja","js","jns","jpe","jpo",
  "jl","jge","jle","jg"
};

static char *ctable[]=
{ "cmovo","cmovno","cmovc","cmovnc","cmovz","cmovnz","cmovbe","cmova","cmovs",
  "cmovns","cmovpe","cmovpo","cmovl","cmovge","cmovle","cmovg"
};

static char *stable[]=
{ "seto","setno","setc","setnc","setz","setnz","setbe","seta","sets","setns",
  "setpe","setpo","setl","setge","setle","setg"
};

disasm::disasm(void)
{ disassembly=NULL;
  lastsib=0;
  addressprefix=FALSE;
  operandprefix=FALSE;
  lastasm=NULL;
  speed=0;
  barct=0;
  codeplus=0;
  instct=0;
}

disasm::~disasm(void)
{ struct asmlist *nxt;
  while(disassembly!=NULL)
  { nxt=disassembly->next;
	 delete disassembly;
	 disassembly=nxt;
  }
}

void disasm::decode(void)
{ struct codedata *code;
  if(comfile)mode32=FALSE;
  else mode32=TRUE;
  xr.addxref(pe_exe.getstart(),0,XREF_START);
  PrintBuff("Decoding refs...");
  PrintBuff("");
  decoderefs();
  code=pe_exe.getcode();
  PrintBuff("Decoding possibles...");
  PrintBuff("");
  while(code!=NULL)
  { decodepossibles(code);
	 code=code->next;
  }
  code=pe_exe.getcode();
  PrintBuff("Decoding rest...");
  PrintBuff("");
  while(code!=NULL)
  { decoderest(code);
	 code=code->next;
  }
  PrintBuff("Decoding data...");
  PrintBuff("");
  code=pe_exe.getinitdata();
  while(code!=NULL)
  { decoderest(code);
	 code=code->next;
  }
}

void disasm::decoderefs(void)
{ struct codedata *code;
  unsigned long ca;
  code=pe_exe.getcode();
  stepsize=code->size/1000;
  while(code->next!=NULL)
  { code=code->next;
	 stepsize+=code->size/1000;
  }
  do
  { ca=xr.nextcode();
	 if(ca)
	 { code=pe_exe.getcode();
		while(code!=NULL)
		{ if((ca<code->addr)||(ca>(code->addr+code->size)))code=code->next;
		  else break;
		}
		if(code!=NULL)decodeblock(code,ca);
	 }
  } while(ca);
}

void disasm::hintdata(unsigned long ip,unsigned char op)
{ unsigned char *dptr;
  dptr=pe_exe.finddata(ip);
  if(dptr!=NULL)
  { switch(op)
	 { case OP_DB:
		  addtoasm(ip,OP_DB,1,dptr,IMM,((unsigned long)(dptr[0])),0,0,0);
		  break;
		case OP_DW:
		  addtoasm(ip,OP_DW,2,dptr,IMM,(((unsigned long)(dptr[0]))<<8)+dptr[1],0,0,0);
		  break;
		case OP_DD:
		  addtoasm(ip,OP_DD,4,dptr,IMM,((unsigned long *)(dptr))[0],0,0,0);
		  break;
		case OP_DS:
		  addtoasm(ip,OP_DS,strlen((char *)dptr)+1,dptr,STR,0,0,0,0);
		  break;
	 }
  }
}

void disasm::decodeblock(struct codedata *block,unsigned long ip)
{ signed long blocksize=block->size;
  unsigned long vsize=block->virt_size;
  unsigned char *blockdata=block->dataptr+(ip-block->addr),lastop,*jdata,*daddr;
  unsigned long instruction_size;
  unsigned long maxip,jaddr,jref,jadded,dref,drefby;
  struct asmlist *asmptr;
  maxip=block->addr+blocksize;
  if(KillThread)return;
  if(disassembly!=NULL)
  { asmptr=disassembly;
	 if(lastasm!=NULL)
      if(lastasm->addr<=ip)asmptr=lastasm;
	 while(asmptr!=NULL)
	 { if(asmptr->addr<ip)
		{ if(asmptr->addr+asmptr->bytelength>ip)return;
		  asmptr=asmptr->next;
		}
		else
		if(asmptr->opcode==OP_DB) asmptr=asmptr->next;
		else
		if(asmptr->addr==ip)return;
		else
		if(asmptr->addr>ip)
		{ maxip=asmptr->addr;
		  break;
		}
	 }
  }
  while(ip<maxip)
  { instruction_size=toasm(ip,blocksize+block->addr-ip,vsize+block->addr-ip,blockdata);
	 ip+=instruction_size;
	 blockdata+=instruction_size;
	 speed+=instruction_size;
    if(KillThread)return;
	 if(speed>stepsize)
	 { barct++;
		Progress_SetPos(ProgressBar,barct);
		speed-=stepsize;
	 }
	 lastop=lastasm->opcode;
	 if((lastop==OP_RETN)||(lastop==OP_RETF)||(lastop==OP_IRET)||(lastop==OP_HLT)||
		(lastop==OP_DB))return;
	 if(lastop==OP_JMP)
	 { lastsib=lastasm->sib;
		if(((lastsib>>3)&7)==4)return;
		if((lastasm->arg1type==DISP32D)||(lastasm->arg1type==MEMLOCD))
		{ if(lastasm->arg1type==MEMLOCD)jaddr=lastasm->arg1;
		  else jaddr=lastasm->displacement;
		  jadded=0;
		  while((jaddr>=block->addr)&&(jaddr<block->addr+block->size))
		  { jdata=block->dataptr+(jaddr-block->addr);
			 jref=((unsigned long *)jdata)[0];
			 if((jref<block->addr)||(jref>block->addr+block->size))break;
			 if(!jadded)
			 { jadded++;
				xr.addxref(jaddr,lastasm->addr,XREF_JUMPTABLE);
			 }
			 addtoasm(jaddr,OP_DD,4,jdata,IMM,jref,0,0,0);
			 xr.addxref(jref,jaddr,XREF_JUMPTABLE);
			 speed+=4;
			 jaddr+=4;
		  }
		}
		return;
	 }
	 if(((lastasm->arg1type==MEMLOC)&&(mode32))||(lastasm->arg1type==MEMLOCD))
	 { daddr=pe_exe.finddata(lastasm->arg1);
		if(daddr!=NULL)
		{ dref=lastasm->arg1;
		  drefby=lastasm->addr;
		  addtoasm(dref,OP_DD,4,daddr,IMM,((unsigned long *)(daddr))[0],0,0,0);
		  xr.addxref(dref,drefby,XREF_DATA);
		}
	 } 
	 if(lastasm->arg1type==MEMLOCB)
	 { daddr=pe_exe.finddata(lastasm->arg1);
		if(daddr!=NULL)
		{ dref=lastasm->arg1;
		  drefby=lastasm->addr;
		  addtoasm(dref,OP_DB,1,daddr,IMM,(unsigned long)(daddr[0]),0,0,0);
		  xr.addxref(dref,drefby,XREF_DATA);
		}
	 } 
	 if(((lastasm->arg1type==MEMLOC)&&(!mode32))||(lastasm->arg1type==MEMLOCW))
	 { daddr=pe_exe.finddata(lastasm->arg1);
		if(daddr!=NULL)
		{ dref=lastasm->arg1;
		  drefby=lastasm->addr;
		  addtoasm(dref,OP_DW,2,daddr,IMM,(((unsigned long)(daddr[0]))<<8)+daddr[1],0,0,0);
		  xr.addxref(dref,drefby,XREF_DATA);
		}
	 }
  }
  if((ip>maxip)&&(ip<block->addr+blocksize))decodeblock(block,ip);
}

void disasm::decodepossibles(struct codedata *block)
{ signed long blocksize;
  unsigned long ip,iplast;
  unsigned char *blockdata,*data;
  unsigned long maxip;
  BOOL done;
  struct asmlist *asmptr;
  blocksize=block->size;
  ip=block->addr;
  blockdata=block->dataptr;
  maxip=block->addr+blocksize;
  asmptr=disassembly;
  while(asmptr!=NULL)
  { if(asmptr->addr<ip)asmptr=asmptr->next;
	 else break;
  }
  while(ip<maxip)
  { if(KillThread)return;
	 done=FALSE;
	 if(asmptr!=NULL)
	 { if(ip==asmptr->addr)
		{ ip+=asmptr->bytelength;
		  done=TRUE;
		  while(asmptr!=NULL)
		  { if(asmptr->addr<ip)asmptr=asmptr->next;
			 else break;
		  }
		}
	 }
	 if(!done)
	 { data=blockdata+ip-block->addr;
		// push ebp
		// mov ebp,esp
		if((data[0]==0x55)&&(data[1]==0x8b)&&(data[2]==0xec))
		{ decodeblock(block,ip);
		  ip+=3;
		  asmptr=disassembly;
		  while(asmptr!=NULL)
		  { if(asmptr->addr<ip)asmptr=asmptr->next;
			 else break;
		  }
		}
		// push reg
		else if((data[0]>=0x50)&&(data[0]<=0x57))
		{ decodeblock(block,ip);
		  ip++;
		  asmptr=disassembly;
		  while(asmptr!=NULL)
		  { if(asmptr->addr<ip)asmptr=asmptr->next;
			 else break;
		  }
		}
		else ip++;
	 }
  }
  decoderefs();
  blocksize=block->size;
  ip=block->addr;
  blockdata=block->dataptr;
  maxip=block->addr+blocksize;
  asmptr=disassembly;
  while(asmptr!=NULL)
  { if(asmptr->addr<ip)asmptr=asmptr->next;
	 else break;
  }
  iplast=0;
  while(ip<maxip)
  { if(KillThread)return;
	 done=FALSE;
	 if(asmptr!=NULL)
	 { if(ip==asmptr->addr)
		{ ip+=asmptr->bytelength;
		  done=TRUE;
		  while(asmptr!=NULL)
		  { if(asmptr->addr<ip)asmptr=asmptr->next;
			 else break;
		  }
		}
	 }

	 if((!done)&&(ip!=iplast))
	 { iplast=ip;
		data=blockdata+ip-block->addr;
		// call (relative)
		// mov r/m32,r32
		// mov r32,r/m32
		// ret
		// jmp
		// pusha
		if((data[0]==0xe8)||(data[0]==0x8b)||(data[0]==0x89)||(data[0]==0xc3)
			||(data[0]==0xe9)||(data[0]==0x60))
		{ decodeblock(block,ip);
		  asmptr=disassembly;
		  while(asmptr!=NULL)
		  { if(asmptr->addr<ip)asmptr=asmptr->next;
			 else break;
		  }
		}
		// push reg
		else if((data[0]>=0x50)&&(data[0]<=0x57))
		{ decodeblock(block,ip);
		  asmptr=disassembly;
		  while(asmptr!=NULL)
		  { if(asmptr->addr<ip)asmptr=asmptr->next;
			 else break;
		  }
		}
		// mov reg,imm
		else if((data[0]>=0xb0)&&(data[0]<=0xbf))
		{ decodeblock(block,ip);
		  asmptr=disassembly;
		  while(asmptr!=NULL)
		  { if(asmptr->addr<ip)asmptr=asmptr->next;
			 else break;
		  }
		}
		// jmp dword ptr
		else if((data[0]==0xff)&&((data[1]==0x25)||(data[1]==0x15)))
		{ decodeblock(block,ip);
		  asmptr=disassembly;
		  while(asmptr!=NULL)
		  { if(asmptr->addr<ip)asmptr=asmptr->next;
			 else break;
		  }
		}
		// code exts
		else if((data[0]==0xc6)||(data[0]==0xc7)||(data[0]==0x80))
		{ decodeblock(block,ip);
		  asmptr=disassembly;
		  while(asmptr!=NULL)
		  { if(asmptr->addr<ip)asmptr=asmptr->next;
			 else break;
		  }
		}
		// test
		// cmp
		// lea
		else if((data[0]==0x85)||(data[0]==0x3c)||(data[0]==0x8d))
		{ decodeblock(block,ip);
		  asmptr=disassembly;
		  while(asmptr!=NULL)
		  { if(asmptr->addr<ip)asmptr=asmptr->next;
			 else break;
		  }
		}
		else ip++;
	 }
	 else if(!done) ip++;
  }
  decoderefs();
}

void disasm::decoderest(struct codedata *block)
{ signed long blocksize=block->size;
  unsigned long ip,stest,asmmax;
  unsigned char *blockdata=block->dataptr;
  unsigned long maxip;
  struct codedata *code;
  BOOL done;
  struct asmlist *asmptr;
  maxip=block->addr+blocksize;
  asmptr=disassembly;
  ip=block->addr;
  while(asmptr!=NULL)
  { if(asmptr->addr<ip)asmptr=asmptr->next;
	 else break;
  }
  while(ip<maxip)
  { if(KillThread)return;
	 done=FALSE;
	 if(asmptr!=NULL)
	 { if(ip==asmptr->addr)
		{ ip+=asmptr->bytelength;
		  done=TRUE;
		  while(asmptr!=NULL)
		  { if(asmptr->addr<ip)asmptr=asmptr->next;
			 else break;
		  }
		}
	 }
	 if(asmptr==NULL)asmmax=maxip-4;
	 else asmmax=asmptr->addr-4;
	 if((!done)&&(ip<maxip-4)&&(mode32))
	 { if(ip<=asmmax)
		{ stest=((unsigned long *)(blockdata+ip-block->addr))[0];
		  if((stest>=block->addr)&&(stest<=block->addr+blocksize))
		  { addtoasm(ip,OP_DD,4,blockdata+ip-block->addr,IMM,stest,0,0,0);
			 xr.addxref(stest,ip,XREF_DATA);
			 ip+=4;
			 done=TRUE;
		  }
		  else
		  { code=pe_exe.getcode();
			 while(code!=NULL)
			 { if((stest>=code->addr)&&(stest<code->addr+code->size))break;
				code=code->next;
			 }
			 if(code!=NULL)
			 { addtoasm(ip,OP_DD,4,blockdata+ip-block->addr,IMM,stest,0,0,0);
				xr.addxref(stest,ip,XREF_JUMPTABLE);
				ip+=4;
				done=TRUE;
			 }
			 else if(relocs.isreloc(ip))
			 { addtoasm(ip,OP_DD,4,blockdata+ip-block->addr,IMM,stest,0,0,0);
				xr.addxref(stest,ip,XREF_DATA);
				ip+=4;
				done=TRUE;
			 }
		  }
		}
	 }
    if(!done)ip++;
  }
  decoderefs();
  asmptr=disassembly;
  ip=block->addr;
  while(asmptr!=NULL)
  { if(asmptr->addr<ip)asmptr=asmptr->next;
	 else break;
  }
  while(ip<maxip)
  { if(KillThread)return;
	 done=FALSE;
	 if(asmptr!=NULL)
	 { if(ip==asmptr->addr)
		{ ip+=asmptr->bytelength;
		  done=TRUE;
		  while(asmptr!=NULL)
		  { if(asmptr->addr<ip)asmptr=asmptr->next;
			 else break;
		  }
		}
	 }
	 if(asmptr==NULL)asmmax=maxip;
	 else asmmax=asmptr->addr;
	 if(!done)
	 { stest=ip;
		while((stest<maxip)&&(stest<asmmax)&&((((blockdata+stest-block->addr)[0]>=0x20)&&
		  ((blockdata+stest-block->addr)[0]<=0x7f))||((blockdata+stest-block->addr)[0]==0x09)||
		  ((blockdata+stest-block->addr)[0]==0x0d)||((blockdata+stest-block->addr)[0]==0x0a)))
		  stest++;
		if((stest<maxip)&&(stest>ip)&&(stest<asmmax)&&((blockdata+stest-block->addr)[0]==0x00))
		{ addtoasm(ip,OP_DS,stest-ip+1,blockdata+ip-block->addr,STR,0,0,0,0);
		  done=TRUE;
		  ip=stest+1;
		}
	 }
	 if(!done)
	 { stest=ip;
		if((blockdata+stest-block->addr)[0]==0x00)
		{ while((stest<maxip)&&(stest<asmmax)&&((blockdata+stest-block->addr)[0]==0x00)) stest++;
		  if(stest-ip<=4)stest=ip+1;
		  if(stest==ip+1)
			 addtoasm(ip,OP_DB,1,blockdata+ip-block->addr,0,0,0,0,0);
		  else
			 addtoasm(ip,OP_ZEROBLOCK,stest-ip,blockdata+ip-block->addr,0,0,0,0,0);
		  ip=stest;
		}
		else
		{ addtoasm(ip,OP_DB,1,blockdata+ip-block->addr,0,0,0,0,0);
		  ip++;
		}
	 }
  }
  decoderefs();
}

#pragma warn -sig

unsigned char disasm::toasm(unsigned long ip,unsigned long bsize,unsigned long vsize,
  unsigned char *data)
{ unsigned char len;
  unsigned char type,opadd;
  unsigned long value,displacement;
  lastsib=0;
  if(!mode32)
  { operandprefix=!operandprefix;
	 addressprefix=!addressprefix;
  }
  if(operandprefix)opadd=8;
  else opadd=0;
  switch(data[0])
  { case 0x00:
		len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_ADD,len,data,type,value,REG,REG_AL+((data[1]>>3)&7),displacement);
		break;
	 case 0x01:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_ADD,len,data,type,value,REG,REG_AX+((data[1]>>3)&7)+opadd,displacement);
		break;
	 case 0x02:
		len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_ADD,len,data,REG,REG_AL+((data[1]>>3)&7),type,value,displacement);
		break;
	 case 0x03:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_ADD,len,data,REG,REG_AX+((data[1]>>3)&7)+opadd,type,value,displacement);
		break;
	 case 0x04:
		addtoasm(ip,OP_ADD,len=2,data,REG,REG_AL,IMM,(unsigned long)data[1],0);
		break;
	 case 0x05:
		if(opadd)
		  addtoasm(ip,OP_ADD,len=3,data,REG,REG_AX+opadd,IMM,(((unsigned long)data[2])<<8)+data[1],0);
		else
		  addtoasm(ip,OP_ADD,len=5,data,REG,REG_AX,IMM,((unsigned long *)(&data[1]))[0],0);
		break;
	 case 0x06:
		addtoasm(ip,OP_PUSH,len=1,data,REG,REG_ES,0,0,0);
		break;
	 case 0x07:
		addtoasm(ip,OP_POP,len=1,data,REG,REG_ES,0,0,0);
		break;
	 case 0x08:
		len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_OR,len,data,type,value,REG,REG_AL+((data[1]>>3)&7),displacement);
		break;
	 case 0x09:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_OR,len,data,type,value,REG,REG_AX+((data[1]>>3)&7)+opadd,displacement);
		break;
	 case 0x0a:
		len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_OR,len,data,REG,REG_AL+((data[1]>>3)&7),type,value,displacement);
		break;
	 case 0x0b:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_OR,len,data,REG,REG_AX+((data[1]>>3)&7)+opadd,type,value,displacement);
		break;
	 case 0x0c:
		addtoasm(ip,OP_OR,len=2,data,REG,REG_AL,IMM,(unsigned long)data[1],0);
		break;
	 case 0x0d:
		if(opadd)
		  addtoasm(ip,OP_OR,len=3,data,REG,REG_AX+opadd,IMM,(((unsigned long)data[2])<<8)+data[1],0);
		else
		  addtoasm(ip,OP_OR,len=5,data,REG,REG_AX,IMM,((unsigned long *)(&data[1]))[0],0);
		break;
	 case 0x0e:
		addtoasm(ip,OP_PUSH,len=1,data,REG,REG_CS,0,0,0);
		break;
	 case 0x0f:
		switch(data[1])
		{ case 0x00:
			 type=(data[2]>>3)&7;
			 if((type==6)||(type==7))
				addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
			 else
			 { len=modrmbyte(&data[2],&type,&value,&displacement)+3;
				if((type==INDIRECT)||(type==DISP8)||(type==DISP32)||(type==MEMLOC))type+=2;
				addtoasm(ip,OP_SLDT+((data[2]>>3)&7),len,data,type,value,0,0,displacement);
			 }
			 break;
		  case 0x01:
			 type=(data[2]>>3)&7;
			 if(type==5)
				addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
			 else if(type==7)
				addtoasm(ip,OP_INVLPG,len=2,data,0,0,0,0,0);
			 else
			 { len=modrmbyte(&data[2],&type,&value,&displacement)+3;
				if((type==INDIRECT)||(type==DISP8)||(type==DISP32)||(type==MEMLOC))type+=2;
				addtoasm(ip,OP_SGDT+((data[2]>>3)&7),len,data,type,value,0,0,displacement);
			 }
			 break;
		  case 0x02:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 addtoasm(ip,OP_LAR,len,data,REG,REG_AX+((data[2]>>3)&7)+opadd,type,value,displacement);
			 break;
		  case 0x03:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 addtoasm(ip,OP_LSL,len,data,REG,REG_AX+((data[2]>>3)&7)+opadd,type,value,displacement);
			 break;
		  case 0x06:
			 addtoasm(ip,OP_CLTS,len=2,data,0,0,0,0,0);
			 break;
		  case 0x08:
			 addtoasm(ip,OP_INVD,len=2,data,0,0,0,0,0);
			 break;
		  case 0x09:
			 addtoasm(ip,OP_WBINVD,len=2,data,0,0,0,0,0);
			 break;
		  case 0x0b:
			 addtoasm(ip,OP_UD2,len=2,data,0,0,0,0,0);
			 break;
		  case 0x20:
			 type=(data[2]>>3)&7;
			 if((type==1)||(type>4))
				addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
			 else
			 { len=modrmbyte(&data[2],&type,&value,&displacement)+3;
				addtoasm(ip,OP_MOV,len,data,type,value,REG,REG_CR0+((data[2]>>3)&7),displacement);
			 }
			 break;
		  case 0x21:
			 type=(data[2]>>3)&7;
			 if((type==4)||(type==5))
				addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
			 else
			 { len=modrmbyte(&data[2],&type,&value,&displacement)+3;
				addtoasm(ip,OP_MOV,len,data,type,value,REG,REG_DR0+((data[2]>>3)&7),displacement);
			 }
			 break;
		  case 0x22:
			 type=(data[2]>>3)&7;
			 if((type==1)||(type>4))
				addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
			 else
			 { len=modrmbyte(&data[2],&type,&value,&displacement)+3;
				addtoasm(ip,OP_MOV,len,data,REG,REG_CR0+((data[2]>>3)&7),type,value,displacement);
			 }
			 break;
		  case 0x23:
			 type=(data[2]>>3)&7;
			 if((type==4)||(type==5))
				addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
			 else
			 { len=modrmbyte(&data[2],&type,&value,&displacement)+3;
				addtoasm(ip,OP_MOV,len,data,REG,REG_DR0+((data[2]>>3)&7),type,value,displacement);
			 }
			 break;
		  case 0x24:
			 type=(data[2]>>3)&7;
			 if(type<3)
				addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
			 else
			 { len=modrmbyte(&data[2],&type,&value,&displacement)+3;
				addtoasm(ip,OP_MOV,len,data,type,value,REG,REG_TR3-3+((data[2]>>3)&7),displacement);
			 }
			 break;
		  case 0x26:
			 type=(data[2]>>3)&7;
			 if(type<3)
				addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
			 else
			 { len=modrmbyte(&data[2],&type,&value,&displacement)+3;
				addtoasm(ip,OP_MOV,len,data,REG,REG_TR3-3+((data[2]>>3)&7),type,value,displacement);
			 }
			 break;
		  case 0x30:
			 addtoasm(ip,OP_WRMSR,len=2,data,0,0,0,0,0);
			 break;
		  case 0x31:
			 addtoasm(ip,OP_RDTSC,len=2,data,0,0,0,0,0);
			 break;
		  case 0x32:
			 addtoasm(ip,OP_RDMSR,len=2,data,0,0,0,0,0);
			 break;
		  case 0x33:
			 addtoasm(ip,OP_RDPMC,len=2,data,0,0,0,0,0);
			 break;
		  case 0x40:
		  case 0x41:
		  case 0x42:
		  case 0x43:
		  case 0x44:
		  case 0x45:
		  case 0x46:
		  case 0x47:
		  case 0x48:
		  case 0x49:
		  case 0x4a:
		  case 0x4b:
		  case 0x4c:
		  case 0x4d:
		  case 0x4e:
		  case 0x4f:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 addtoasm(ip,OP_CMOVO+data[1]-0x40,len,data,REG,REG_AX+((data[2]>>3)&7)+opadd,
				type,value,displacement);
			 break;
		  case 0x60:
		  case 0x61:
		  case 0x62:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(((data[2]>>6)&3)==3)
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  REG,REG_MM0+(data[2]&7),displacement);
			 else
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  type+1+data[1]-0x60,value,displacement);
			 lastasm->thirdarg=MMX_PUNPCKL;
			 break;
		  case 0x63:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(((data[2]>>6)&3)==3)
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  REG,REG_MM0+(data[2]&7),displacement);
			 else
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  type+2,value,displacement);
			 lastasm->thirdarg=MMX_PACKSS;
			 break;
		  case 0x64:
		  case 0x65:
		  case 0x66:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(((data[2]>>6)&3)==3)
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  REG,REG_MM0+(data[2]&7),displacement);
			 else
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  type+1+data[1]-0x64,value,displacement);
			 lastasm->thirdarg=MMX_PCMPGT;
			 break;
		  case 0x67:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(((data[2]>>6)&3)==3)
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  REG,REG_MM0+(data[2]&7),displacement);
			 else
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  type+2,value,displacement);
			 lastasm->thirdarg=MMX_PACKUS;
			 break;
		  case 0x68:
		  case 0x69:
		  case 0x6a:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(((data[2]>>6)&3)==3)
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  REG,REG_MM0+(data[2]&7),displacement);
			 else
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  type+1+data[1]-0x68,value,displacement);
			 lastasm->thirdarg=MMX_PUNPCKH;
			 break;
		  case 0x6b:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(((data[2]>>6)&3)==3)
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  REG,REG_MM0+(data[2]&7),displacement);
			 else
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  type+3,value,displacement);
			 lastasm->thirdarg=MMX_PACKSS;
			 break;
		  case 0x6e:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),type,value,displacement);
			 lastasm->thirdarg=MMX_MOVD;
			 break;
		  case 0x6f:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(type==REG)value=REG_MM0+(data[2]&7);
			 addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),type,value,displacement);
			 lastasm->thirdarg=MMX_MOVQ;
			 break;
		  case 0x71:
		  case 0x72:
		  case 0x73:
			 type=(data[2]>>3)&7;
			 if((type==0)||(type==1)||(type==3)||(type==5)||(type==7))
				addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
			 else
			 { len=modrmbyte(&data[2],&type,&value,&displacement)+3;
				if(((data[2]>>6)&3)==3)
				{ addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+(data[2]&7),IMM,(unsigned long)data[3],displacement);
				  len++;
				}
				else
				  addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+(data[2]&7),type+1+data[1]-0x71,value,displacement);
				switch((data[2]>>3)&7)
				{ case 2:
					 lastasm->thirdarg=MMX_PSRL;
					 break;
				  case 4:
					 lastasm->thirdarg=MMX_PSRA;
					 break;
				  case 6:
					 lastasm->thirdarg=MMX_PSLL;
					 break;
				}
			 }
			 break;
		  case 0x74:
		  case 0x75:
		  case 0x76:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(((data[2]>>6)&3)==3)
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  REG,REG_MM0+(data[2]&7),displacement);
			 else
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  type+1+data[1]-0x74,value,displacement);
			 lastasm->thirdarg=MMX_PCMPEQ;
			 break;
		  case 0x77:
			 addtoasm(ip,OP_MMX,len=2,data,0,0,0,0,0);
			 lastasm->thirdarg=MMX_EMMS;
			 break;
		  case 0x7e:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 addtoasm(ip,OP_MMX,len,data,type,value,REG,REG_MM0+((data[2]>>3)&7),displacement);
			 lastasm->thirdarg=MMX_MOVD;
			 break;
		  case 0x7f:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(type==REG)value=REG_MM0+(data[2]&7);
			 addtoasm(ip,OP_MMX,len,data,type,value,REG,REG_MM0+((data[2]>>3)&7),displacement);
			 lastasm->thirdarg=MMX_MOVQ;
			 break;
		  case 0x80:
		  case 0x81:
		  case 0x82:
		  case 0x83:
		  case 0x84:
		  case 0x85:
		  case 0x86:
		  case 0x87:
		  case 0x88:
		  case 0x89:
		  case 0x8a:
		  case 0x8b:
		  case 0x8c:
		  case 0x8d:
		  case 0x8e:
		  case 0x8f:
			 if(operandprefix)
			 {	if(data[2]>0x80)
				  addtoasm(ip,OP_JO+data[1]-0x80,len=4,data,MEM,
						  ip+((unsigned long)((data[3]<<8)+data[2])+0xffff0000)+4,0,0,0);
				else
				  addtoasm(ip,OP_JO+data[1]-0x80,len=4,data,MEM,
						  ip+((unsigned long)((data[3]<<8)+data[2]))+4,0,0,0);
			 }
			 else
				addtoasm(ip,OP_JO+data[1]-0x80,len=6,data,MEM,
						  ip+((unsigned long *)(&data[2]))[0]+6,0,0,0);
			 xr.addxref(lastasm->arg1,lastasm->addr,XREF_JUMP);
			 break;
		  case 0x90:
		  case 0x91:
		  case 0x92:
		  case 0x93:
		  case 0x94:
		  case 0x95:
		  case 0x96:
		  case 0x97:
		  case 0x98:
		  case 0x99:
		  case 0x9a:
		  case 0x9b:
		  case 0x9c:
		  case 0x9d:
		  case 0x9e:
		  case 0x9f:
			 len=modrm8byte(&data[2],&type,&value,&displacement)+3;
			 addtoasm(ip,OP_SETO+data[1]-0x90,len,data,type,value,0,0,displacement);
			 break;
		  case 0xa0:
			 addtoasm(ip,OP_PUSH,len=2,data,REG,REG_FS,0,0,0);
			 break;
		  case 0xa1:
			 addtoasm(ip,OP_POP,len=2,data,REG,REG_FS,0,0,0);
			 break;
		  case 0xa2:
			 addtoasm(ip,OP_CPUID,len=2,data,0,0,0,0,0);
			 break;
		  case 0xa3:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 addtoasm(ip,OP_BT,len,data,type,value,REG,REG_AX+((data[2]>>3)&7)+opadd,displacement);
			 break;
		  case 0xa4:
			 if(addressprefix)
			 { len=modrm16byte(&data[1],&type,&value,&displacement)+4;
				addtoasm(ip,OP_SHLDI,len,data,REG,REG_AX+((data[1]>>3)&7)+opadd,type,value,displacement);
				lastasm->thirdarg=(unsigned long)(data[len-1]);
			 }
			 else
			 { len=modrmbyte(&data[2],&type,&value,&displacement)+4;
				addtoasm(ip,OP_SHLDI,len,data,REG,REG_AX+((data[1]>>3)&7)+opadd,type,value,displacement);
				lastasm->thirdarg=(unsigned long)(data[len-1]);
			 }
			 break;
		  case 0xa5:
			 if(addressprefix)
			 { len=modrm16byte(&data[1],&type,&value,&displacement)+3;
				addtoasm(ip,OP_SHLDCL,len,data,REG,REG_AX+((data[1]>>3)&7)+opadd,type,value,displacement);
			 }
			 else
			 { len=modrmbyte(&data[2],&type,&value,&displacement)+3;
				addtoasm(ip,OP_SHLDCL,len,data,REG,REG_AX+((data[1]>>3)&7)+opadd,type,value,displacement);
			 }
			 break;
		  case 0xa8:
			 addtoasm(ip,OP_PUSH,len=2,data,REG,REG_GS,0,0,0);
			 break;
		  case 0xa9:
			 addtoasm(ip,OP_POP,len=2,data,REG,REG_GS,0,0,0);
			 break;
		  case 0xaa:
			 addtoasm(ip,OP_RSM,len=2,data,0,0,0,0,0);
			 break;
		  case 0xab:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 addtoasm(ip,OP_BTS,len,data,type,value,REG,REG_AX+((data[2]>>3)&7)+opadd,displacement);
			 break;
		  case 0xac:
			 if(addressprefix)
			 { len=modrm16byte(&data[1],&type,&value,&displacement)+4;
				addtoasm(ip,OP_SHRDI,len,data,REG,REG_AX+((data[1]>>3)&7)+opadd,type,value,displacement);
				lastasm->thirdarg=(unsigned long)(data[len-1]);
			 }
			 else
			 { len=modrmbyte(&data[2],&type,&value,&displacement)+4;
				addtoasm(ip,OP_SHRDI,len,data,REG,REG_AX+((data[1]>>3)&7)+opadd,type,value,displacement);
				lastasm->thirdarg=(unsigned long)(data[len-1]);
			 }
			 break;
		  case 0xad:
			 if(addressprefix)
			 { len=modrm16byte(&data[1],&type,&value,&displacement)+3;
				addtoasm(ip,OP_SHRDCL,len,data,REG,REG_AX+((data[1]>>3)&7)+opadd,type,value,displacement);
			 }
			 else
			 { len=modrmbyte(&data[2],&type,&value,&displacement)+3;
				addtoasm(ip,OP_SHRDCL,len,data,REG,REG_AX+((data[1]>>3)&7)+opadd,type,value,displacement);
			 }
			 break;
		  case 0xaf:
			 if(addressprefix)
			 { len=modrm16byte(&data[2],&type,&value,&displacement)+3;
				addtoasm(ip,OP_IMUL,len,data,REG,REG_AX+((data[2]>>3)&7)+opadd,type,value,displacement);
				lastasm->thirdarg=1;
			 }
			 else
			 { len=modrmbyte(&data[2],&type,&value,&displacement)+3;
				addtoasm(ip,OP_IMUL,len,data,REG,REG_AX+((data[2]>>3)&7)+opadd,type,value,displacement);
				lastasm->thirdarg=1;
			 }
			 break;
		  case 0xb0:
			 len=modrm8byte(&data[2],&type,&value,&displacement)+3;
			 addtoasm(ip,OP_CMPXCH,len,data,type,value,REG,REG_AL+((data[2]>>3)&7),displacement);
			 break;
		  case 0xb1:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 addtoasm(ip,OP_CMPXCH,len,data,type,value,REG,REG_AX+((data[2]>>3)&7)+opadd,displacement);
			 break;
		  case 0xb2:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 addtoasm(ip,OP_LSS,len,data,type,value,REG,REG_AX+((data[2]>>3)&7)+opadd,displacement);
			 break;
		  case 0xb3:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 addtoasm(ip,OP_BTR,len,data,type,value,REG,REG_AX+((data[2]>>3)&7)+opadd,displacement);
			 break;
		  case 0xb4:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 addtoasm(ip,OP_LFS,len,data,type,value,REG,REG_AX+((data[2]>>3)&7)+opadd,displacement);
			 break;
		  case 0xb5:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 addtoasm(ip,OP_LGS,len,data,type,value,REG,REG_AX+((data[2]>>3)&7)+opadd,displacement);
			 break;
		  case 0xb6:
			 len=modrm8byte(&data[2],&type,&value,&displacement)+3;
			 if((type==INDIRECT)||(type==DISP8)||(type==DISP32)||(type==MEMLOC))type+=1;
			 addtoasm(ip,OP_MOVZX,len,data,REG,REG_AX+((data[2]>>3)&7)+opadd,type,value,displacement);
			 break;
		  case 0xb7:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if((type==INDIRECT)||(type==DISP8)||(type==DISP32)||(type==MEMLOC))type+=2;
			 else value+=8;
			 addtoasm(ip,OP_MOVZX,len,data,REG,REG_AX+((data[2]>>3)&7)+opadd,type,value,displacement);
			 break;
		  case 0xba:
			 type=(data[2]>>3)&7;
			 if(type<4)
				addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
			 else
			 { len=modrmbyte(&data[2],&type,&value,&displacement)+4;
				switch((data[2]>>3)&7)
				{ case 4:
					 addtoasm(ip,OP_BT,len,data,type,value,IMM,
						(unsigned long)data[len-1],displacement);
					 break;
				  case 5:
					 addtoasm(ip,OP_BTS,len,data,type,value,IMM,
						(unsigned long)data[len-1],displacement);
					 break;
				  case 6:
					 addtoasm(ip,OP_BTR,len,data,type,value,IMM,
						(unsigned long)data[len-1],displacement);
					 break;
				  case 7:
					 addtoasm(ip,OP_BTC,len,data,type,value,IMM,
						(unsigned long)data[len-1],displacement);
					 break;
				}
			 }
			 break;
		  case 0xbb:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 addtoasm(ip,OP_BTC,len,data,type,value,REG,REG_AX+((data[2]>>3)&7)+opadd,displacement);
			 break;
		  case 0xbc:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 addtoasm(ip,OP_BSF,len,data,type,value,REG,REG_AX+((data[2]>>3)&7)+opadd,displacement);
			 break;
		  case 0xbd:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 addtoasm(ip,OP_BSR,len,data,type,value,REG,REG_AX+((data[2]>>3)&7)+opadd,displacement);
			 break;
		  case 0xbe:
			 len=modrm8byte(&data[2],&type,&value,&displacement)+3;
			 if((type==INDIRECT)||(type==DISP8)||(type==DISP32)||(type==MEMLOC))type+=1;
			 addtoasm(ip,OP_MOVSX,len,data,REG,REG_AX+((data[2]>>3)&7)+opadd,type,value,displacement);
			 break;
		  case 0xbf:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if((type==INDIRECT)||(type==DISP8)||(type==DISP32)||(type==MEMLOC))type+=2;
			 else value+=8;
			 addtoasm(ip,OP_MOVSX,len,data,REG,REG_AX+((data[2]>>3)&7)+opadd,type,value,displacement);
			 break;
		  case 0xc0:
			 len=modrm8byte(&data[2],&type,&value,&displacement)+3;
			 addtoasm(ip,OP_XADD,len,data,type,value,REG,REG_AL+((data[2]>>3)&7),displacement);
			 break;
		  case 0xc1:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 addtoasm(ip,OP_XADD,len,data,type,value,REG,REG_AX+((data[2]>>3)&7)+opadd,displacement);
			 break;
		  case 0xc7:
			 type=(data[2]>>3)&7;
			 if((((data[2]>>3)&7)!=1)||((data[2]>>6)==3))
				addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
			 else
			 { len=modrmbyte(&data[2],&type,&value,&displacement)+3;
				addtoasm(ip,OP_CMPXCH8B,len,data,type+4,value,0,0,displacement);
			 }
			 break;
		  case 0xc8:
		  case 0xc9:
		  case 0xca:
		  case 0xcb:
		  case 0xcc:
		  case 0xcd:
		  case 0xce:
		  case 0xcf:
			 addtoasm(ip,OP_BSWAP,len=2,data,REG,REG_AX+data[1]-0xc8,0,0,0);
			 break;
		  case 0xd1:
		  case 0xd2:
		  case 0xd3:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(((data[2]>>6)&3)==3)
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  REG,REG_MM0+(data[2]&7),displacement);
			 else
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  type+2+data[1]-0xd1,value,displacement);
			 lastasm->thirdarg=MMX_PSRL;
			 break;
		  case 0xd5:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(type==REG)value=REG_MM0+(data[2]&7);
			 addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),type,value,displacement);
			 lastasm->thirdarg=MMX_PMULL;
			 break;
		  case 0xd8:
		  case 0xd9:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(((data[2]>>6)&3)==3)
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  REG,REG_MM0+(data[2]&7),displacement);
			 else
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  type+2+data[1]-0xd8,value,displacement);
			 lastasm->thirdarg=MMX_PSUBUS;
			 break;
		  case 0xdb:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(type==REG)value=REG_MM0+(data[2]&7);
			 addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),type,value,displacement);
			 lastasm->thirdarg=MMX_PAND;
			 break;
		  case 0xdc:
		  case 0xdd:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(((data[2]>>6)&3)==3)
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  REG,REG_MM0+(data[2]&7),displacement);
			 else
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  type+2+data[1]-0xdc,value,displacement);
			 lastasm->thirdarg=MMX_PADDUS;
			 break;
		  case 0xdf:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(type==REG)value=REG_MM0+(data[2]&7);
			 addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),type,value,displacement);
			 lastasm->thirdarg=MMX_PANDN;
			 break;
		  case 0xe1:
		  case 0xe2:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(((data[2]>>6)&3)==3)
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  REG,REG_MM0+(data[2]&7),displacement);
			 else
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  type+2+data[1]-0xe1,value,displacement);
			 lastasm->thirdarg=MMX_PSRA;
			 break;
		  case 0xe5:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(type==REG)value=REG_MM0+(data[2]&7);
			 addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),type,value,displacement);
			 lastasm->thirdarg=MMX_PMULH;
			 break;
		  case 0xe8:
		  case 0xe9:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(((data[2]>>6)&3)==3)
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  REG,REG_MM0+(data[2]&7),displacement);
			 else
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  type+2+data[1]-0xe8,value,displacement);
			 lastasm->thirdarg=MMX_PSUBS;
			 break;
		  case 0xeb:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(type==REG)value=REG_MM0+(data[2]&7);
			 addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),type,value,displacement);
			 lastasm->thirdarg=MMX_POR;
			 break;
		  case 0xec:
		  case 0xed:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(((data[2]>>6)&3)==3)
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  REG,REG_MM0+(data[2]&7),displacement);
			 else
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  type+2+data[1]-0xec,value,displacement);
			 lastasm->thirdarg=MMX_PADDS;
			 break;
		  case 0xef:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(type==REG)value=REG_MM0+(data[2]&7);
			 addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),type,value,displacement);
			 lastasm->thirdarg=MMX_PXOR;
			 break;
		  case 0xf1:
		  case 0xf2:
		  case 0xf3:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(((data[2]>>6)&3)==3)
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  REG,REG_MM0+(data[2]&7),displacement);
			 else
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  type+2+data[1]-0xf1,value,displacement);
			 lastasm->thirdarg=MMX_PSLL;
			 break;
		  case 0xf5:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(type==REG)value=REG_MM0+(data[2]&7);
			 addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),type,value,displacement);
			 lastasm->thirdarg=MMX_PMADD;
			 break;
		  case 0xf8:
		  case 0xf9:
		  case 0xfa:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(((data[2]>>6)&3)==3)
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  REG,REG_MM0+(data[2]&7),displacement);
			 else
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  type+2+data[1]-0xf8,value,displacement);
			 lastasm->thirdarg=MMX_PSUB;
			 break;
		  case 0xfc:
		  case 0xfd:
		  case 0xfe:
			 len=modrmbyte(&data[2],&type,&value,&displacement)+3;
			 if(((data[2]>>6)&3)==3)
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  REG,REG_MM0+(data[2]&7),displacement);
			 else
				addtoasm(ip,OP_MMX,len,data,REG,REG_MM0+((data[2]>>3)&7),
				  type+2+data[1]-0xfc,value,displacement);
			 lastasm->thirdarg=MMX_PADD;
			 break;
		  default:
			 addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
			 break;
		}
		break;
	 case 0x10:
		len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_ADC,len,data,type,value,REG,REG_AL+((data[1]>>3)&7),displacement);
		break;
	 case 0x11:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_ADC,len,data,type,value,REG,REG_AX+((data[1]>>3)&7)+opadd,displacement);
		break;
	 case 0x12:
		len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_ADC,len,data,REG,REG_AL+((data[1]>>3)&7),type,value,displacement);
		break;
	 case 0x13:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_ADC,len,data,REG,REG_AX+((data[1]>>3)&7)+opadd,type,value,displacement);
		break;
	 case 0x14:
		addtoasm(ip,OP_ADC,len=2,data,REG,REG_AL,IMM,(unsigned long)data[1],0);
		break;
	 case 0x15:
		if(opadd)
		  addtoasm(ip,OP_ADC,len=3,data,REG,REG_AX+opadd,IMM,(((unsigned long)data[2])<<8)+data[1],0);
		else
		  addtoasm(ip,OP_ADC,len=5,data,REG,REG_AX,IMM,((unsigned long *)(&data[1]))[0],0);
		break;
	 case 0x16:
		addtoasm(ip,OP_PUSH,len=1,data,REG,REG_SS,0,0,0);
		break;
	 case 0x17:
		addtoasm(ip,OP_POP,len=1,data,REG,REG_SS,0,0,0);
		break;
	 case 0x18:
		len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_SBB,len,data,type,value,REG,REG_AL+((data[1]>>3)&7),displacement);
		break;
	 case 0x19:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_SBB,len,data,type,value,REG,REG_AX+((data[1]>>3)&7)+opadd,displacement);
		break;
	 case 0x1a:
		len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_SBB,len,data,REG,REG_AL+((data[1]>>3)&7),type,value,displacement);
		break;
	 case 0x1b:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_SBB,len,data,REG,REG_AX+((data[1]>>3)&7)+opadd,type,value,displacement);
		break;
	 case 0x1c:
		addtoasm(ip,OP_SBB,len=2,data,REG,REG_AL,IMM,(unsigned long)data[1],0);
		break;
	 case 0x1d:
		if(opadd)
		  addtoasm(ip,OP_SBB,len=3,data,REG,REG_AX+opadd,IMM,(((unsigned long)data[2])<<8)+data[1],0);
		else
		  addtoasm(ip,OP_SBB,len=5,data,REG,REG_AX,IMM,((unsigned long *)(&data[1]))[0],0);
		break;
	 case 0x1e:
		addtoasm(ip,OP_PUSH,len=1,data,REG,REG_DS,0,0,0);
		break;
	 case 0x1f:
		addtoasm(ip,OP_POP,len=1,data,REG,REG_DS,0,0,0);
		break;
	 case 0x20:
		len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_AND,len,data,type,value,REG,REG_AL+((data[1]>>3)&7),displacement);
		break;
	 case 0x21:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_AND,len,data,type,value,REG,REG_AX+((data[1]>>3)&7)+opadd,displacement);
		break;
	 case 0x22:
		len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_AND,len,data,REG,REG_AL+((data[1]>>3)&7),type,value,displacement);
		break;
	 case 0x23:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_AND,len,data,REG,REG_AX+((data[1]>>3)&7)+opadd,type,value,displacement);
		break;
	 case 0x24:
		addtoasm(ip,OP_AND,len=2,data,REG,REG_AL,IMM,(unsigned long)data[1],0);
		break;
	 case 0x25:
		if(opadd)
		  addtoasm(ip,OP_AND,len=3,data,REG,REG_AX+opadd,IMM,(((unsigned long)data[2])<<8)+data[1],0);
		else
		  addtoasm(ip,OP_AND,len=5,data,REG,REG_AX,IMM,((unsigned long *)(&data[1]))[0],0);
		break;
	 case 0x26:
		if(!mode32)
		{ operandprefix=!operandprefix;
		  addressprefix=!addressprefix;
		}
		codeplus++;
		len=toasm(ip+1,bsize,vsize,&data[1])+1;
		codeplus--;
		if(!mode32)
		{ operandprefix=!operandprefix;
		  addressprefix=!addressprefix;
		}
		lastasm->segprefix=REG_ES;
		break;
	 case 0x27:
		addtoasm(ip,OP_DAA,len=1,data,0,0,0,0,0);
		break;
	 case 0x28:
		len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_SUB,len,data,type,value,REG,REG_AL+((data[1]>>3)&7),displacement);
		break;
	 case 0x29:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_SUB,len,data,type,value,REG,REG_AX+((data[1]>>3)&7)+opadd,displacement);
		break;
	 case 0x2a:
		len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_SUB,len,data,REG,REG_AL+((data[1]>>3)&7),type,value,displacement);
		break;
	 case 0x2b:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_SUB,len,data,REG,REG_AX+((data[1]>>3)&7)+opadd,type,value,displacement);
		break;
	 case 0x2c:
		addtoasm(ip,OP_SUB,len=2,data,REG,REG_AL,IMM,(unsigned long)data[1],0);
		break;
	 case 0x2d:
		if(opadd)
		  addtoasm(ip,OP_SUB,len=3,data,REG,REG_AX+opadd,IMM,(((unsigned long)data[2])<<8)+data[1],0);
		else
		  addtoasm(ip,OP_SUB,len=5,data,REG,REG_AX,IMM,((unsigned long *)(&data[1]))[0],0);
		break;
	 case 0x2e:
		if(!mode32)
		{ operandprefix=!operandprefix;
		  addressprefix=!addressprefix;
		}
		codeplus++;
		len=toasm(ip+1,bsize,vsize,&data[1])+1;
		codeplus--;
		if(!mode32)
		{ operandprefix=!operandprefix;
		  addressprefix=!addressprefix;
		}
		lastasm->segprefix=REG_CS;
		break;
	 case 0x2f:
		addtoasm(ip,OP_DAS,len=1,data,0,0,0,0,0);
		break;
	 case 0x30:
		len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_XOR,len,data,type,value,REG,REG_AL+((data[1]>>3)&7),displacement);
		break;
	 case 0x31:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_XOR,len,data,type,value,REG,REG_AX+((data[1]>>3)&7)+opadd,displacement);
		break;
	 case 0x32:
		len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_XOR,len,data,REG,REG_AL+((data[1]>>3)&7),type,value,displacement);
		break;
	 case 0x33:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_XOR,len,data,REG,REG_AX+((data[1]>>3)&7)+opadd,type,value,displacement);
		break;
	 case 0x34:
		addtoasm(ip,OP_XOR,len=2,data,REG,REG_AL,IMM,(unsigned long)data[1],0);
		break;
	 case 0x35:
		if(opadd)
		  addtoasm(ip,OP_XOR,len=3,data,REG,REG_AX+opadd,IMM,(((unsigned long)data[2])<<8)+data[1],0);
		else
		  addtoasm(ip,OP_XOR,len=5,data,REG,REG_AX,IMM,((unsigned long *)(&data[1]))[0],0);
		break;
	 case 0x36:
		if(!mode32)
		{ operandprefix=!operandprefix;
		  addressprefix=!addressprefix;
		}
		codeplus++;
		len=toasm(ip+1,bsize,vsize,&data[1])+1;
		codeplus--;
		if(!mode32)
		{ operandprefix=!operandprefix;
		  addressprefix=!addressprefix;
		}
		lastasm->segprefix=REG_SS;
		break;
	 case 0x37:
		addtoasm(ip,OP_AAA,len=1,data,0,0,0,0,0);
		break;
	 case 0x38:
		len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_CMP,len,data,type,value,REG,REG_AL+((data[1]>>3)&7),displacement);
		break;
	 case 0x39:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_CMP,len,data,type,value,REG,REG_AX+((data[1]>>3)&7)+opadd,displacement);
		break;
	 case 0x3a:
		len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_CMP,len,data,REG,REG_AL+((data[1]>>3)&7),type,value,displacement);
		break;
	 case 0x3b:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_CMP,len,data,REG,REG_AX+((data[1]>>3)&7)+opadd,type,value,displacement);
		break;
	 case 0x3c:
		addtoasm(ip,OP_CMP,len=2,data,REG,REG_AL,IMM,(unsigned long)data[1],0);
		break;
	 case 0x3d:
		if(opadd)
		  addtoasm(ip,OP_CMP,len=3,data,REG,REG_AX+opadd,IMM,(((unsigned long)data[2])<<8)+data[1],0);
		else
		  addtoasm(ip,OP_CMP,len=5,data,REG,REG_AX,IMM,((unsigned long *)(&data[1]))[0],0);
		break;
	 case 0x3e:
		if(!mode32)
		{ operandprefix=!operandprefix;
		  addressprefix=!addressprefix;
		}
		codeplus++;
		len=toasm(ip+1,bsize,vsize,&data[1])+1;
		codeplus--;
		if(!mode32)
		{ operandprefix=!operandprefix;
		  addressprefix=!addressprefix;
		}
		lastasm->segprefix=REG_DS;
		break;
	 case 0x3f:
		addtoasm(ip,OP_AAS,len=1,data,0,0,0,0,0);
		break;
	 case 0x40:
	 case 0x41:
	 case 0x42:
	 case 0x43:
	 case 0x44:
	 case 0x45:
	 case 0x46:
	 case 0x47:
		addtoasm(ip,OP_INC,len=1,data,REG,data[0]-0x3f+opadd,0,0,0);
		break;
	 case 0x48:
	 case 0x49:
	 case 0x4a:
	 case 0x4b:
	 case 0x4c:
	 case 0x4d:
	 case 0x4e:
	 case 0x4f:
		addtoasm(ip,OP_DEC,len=1,data,REG,data[0]-0x47+opadd,0,0,0);
		break;
	 case 0x50:
	 case 0x51:
	 case 0x52:
	 case 0x53:
	 case 0x54:
	 case 0x55:
	 case 0x56:
	 case 0x57:
		addtoasm(ip,OP_PUSH,len=1,data,REG,data[0]-0x4f+opadd,0,0,0);
		break;
	 case 0x58:
	 case 0x59:
	 case 0x5a:
	 case 0x5b:
	 case 0x5c:
	 case 0x5d:
	 case 0x5e:
	 case 0x5f:
		addtoasm(ip,OP_POP,len=1,data,REG,data[0]-0x57+opadd,0,0,0);
		break;
	 case 0x60:
		addtoasm(ip,OP_PUSHA,len=1,data,0,0,0,0,0);
		break;
	 case 0x61:
		addtoasm(ip,OP_POPA,len=1,data,0,0,0,0,0);
		break;
	 case 0x62:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_BOUND,len,data,REG,REG_AX+((data[1]>>3)&7)+opadd,type,value,displacement);
		break;
	 case 0x63:
		len=modrmbyte(&data[1],&type,&value,&displacement)+4;
		addtoasm(ip,OP_ARPL,len,data,type,value,REG,REG_AX+((data[1]>>3)&7)+8,displacement);
		break;
	 case 0x64:
		if(!mode32)
		{ operandprefix=!operandprefix;
		  addressprefix=!addressprefix;
		}
		codeplus++;
		len=toasm(ip+1,bsize,vsize,&data[1])+1;
		codeplus--;
		if(!mode32)
		{ operandprefix=!operandprefix;
		  addressprefix=!addressprefix;
		}
		lastasm->segprefix=REG_FS;
		break;
	 case 0x65:
		if(!mode32)
		{ operandprefix=!operandprefix;
		  addressprefix=!addressprefix;
		}
		codeplus++;
		len=toasm(ip+1,bsize,vsize,&data[1])+1;
		codeplus--;
		if(!mode32)
		{ operandprefix=!operandprefix;
		  addressprefix=!addressprefix;
		}
		lastasm->segprefix=REG_GS;
		break;
	 case 0x66:
		operandprefix=mode32;
		codeplus++;
		len=toasm(ip+1,bsize,vsize,&data[1])+1;
		codeplus--;
		operandprefix=!mode32;
		break;
	 case 0x67:
		addressprefix=mode32;
		codeplus++;
		len=toasm(ip+1,bsize,vsize,&data[1])+1;
		codeplus--;
		addressprefix=!mode32;
		break;
	 case 0x68:
		if(opadd)
		  addtoasm(ip,OP_PUSH,len=3,data,IMMW,(((unsigned long)data[2])<<8)+data[1],0,0,0);
		else
		  addtoasm(ip,OP_PUSH,len=5,data,IMM,((unsigned long *)(&data[1]))[0],0,0,0);
		if(relocs.isreloc(ip+1))
		{ lastasm->arg1type=OFFSET;
		  xr.addxref(lastasm->arg1,lastasm->addr,XREF_DATA);
		}
		break;
	 case 0x69:
		if(addressprefix)
		{ len=modrm16byte(&data[1],&type,&value,&displacement)+4;
		  addtoasm(ip,OP_IMUL,len,data,REG,REG_AX+((data[1]>>3)&7)+opadd,type,value,displacement);
		  lastasm->thirdarg=((unsigned long)(data[len-2]+(((unsigned long)data[len-1])<<8)));
		}
		else
		{ len=modrmbyte(&data[1],&type,&value,&displacement)+6;
		  addtoasm(ip,OP_IMUL,len,data,REG,REG_AX+((data[1]>>3)&7)+opadd,type,value,displacement);
		  lastasm->thirdarg=((unsigned long *)(&data[len-4]))[0];
		}
		break;
	 case 0x6a:
		if(data[1]>0x80)
		  addtoasm(ip,OP_PUSH,len=2,data,IMM,(unsigned long)(data[1])+0xffffff00,0,0,0);
		else
		  addtoasm(ip,OP_PUSH,len=2,data,IMM,(unsigned long)(data[1]),0,0,0);
		break;
	 case 0x6b:
		len=modrmbyte(&data[1],&type,&value,&displacement)+3;
		addtoasm(ip,OP_IMUL,len,data,REG,REG_AX+((data[1]>>3)&7)+opadd,type,value,displacement);
		lastasm->thirdarg=(unsigned long)(data[len-1]);
		break;
	 case 0x6c:
		addtoasm(ip,OP_INSB,len=1,data,0,0,0,0,0);
		break;
	 case 0x6d:
		if(addressprefix)
		  addtoasm(ip,OP_INSW,len=1,data,0,0,0,0,0);
		else
		  addtoasm(ip,OP_INSD,len=1,data,0,0,0,0,0);
		break;
	 case 0x6e:
		addtoasm(ip,OP_OUTSB,len=1,data,0,0,0,0,0);
		break;
	 case 0x6f:
		if(addressprefix)
		  addtoasm(ip,OP_OUTSW,len=1,data,0,0,0,0,0);
		else
		  addtoasm(ip,OP_OUTSD,len=1,data,0,0,0,0,0);
		break;
	 case 0x70:
	 case 0x71:
	 case 0x72:
	 case 0x73:
	 case 0x74:
	 case 0x75:
	 case 0x76:
	 case 0x77:
	 case 0x78:
	 case 0x79:
	 case 0x7a:
	 case 0x7b:
	 case 0x7c:
	 case 0x7d:
	 case 0x7e:
	 case 0x7f:
		if(data[1]<0x80)
		  addtoasm(ip,OP_JO+data[0]-0x70,len=2,data,MEM,ip+(unsigned long)(data[1])+2,0,0,0);
		else
		  addtoasm(ip,OP_JO+data[0]-0x70,len=2,data,MEM,ip+(unsigned long)(data[1])+0xffffff00+2,0,0,0);
		xr.addxref(lastasm->arg1,lastasm->addr,XREF_JUMP);
		break;
	 case 0x80:
		len=modrm8byte(&data[1],&type,&value,&displacement)+3;
		if((type==INDIRECT)||(type==DISP8)||(type==DISP32)||(type==MEMLOC))type+=1;
		addtoasm(ip,OP_ADD+((data[1]>>3)&7),len,data,type,value,IMM,(unsigned long)data[len-1],displacement);
		break;
	 case 0x81:
		if(opadd)
		{ len=modrmbyte(&data[1],&type,&value,&displacement)+4;
		  if((type==INDIRECT)||(type==DISP8)||(type==DISP32)||(type==MEMLOC))type+=2;
		  addtoasm(ip,OP_ADD+((data[1]>>3)&7),len,data,type,value,IMM,((unsigned long)(data[len-1])<<8)+data[len-2]
						 ,displacement);
		}
		else
		{ len=modrmbyte(&data[1],&type,&value,&displacement)+6;
		  if((type==INDIRECT)||(type==DISP8)||(type==DISP32)||(type==MEMLOC))type+=3;
		  addtoasm(ip,OP_ADD+((data[1]>>3)&7),len,data,type,value,IMM,((unsigned long *)(&data[len-4]))[0]
						 ,displacement);
		}
		break;
	 case 0x82:
		type=(data[1]>>3)&7;
		len=modrm8byte(&data[1],&type,&value,&displacement)+3;
		if((type==INDIRECT)||(type==DISP8)||(type==DISP32)||(type==MEMLOC))type+=1;
		addtoasm(ip,OP_ADD+((data[1]>>3)&7),len,data,type,value,IMM,(unsigned long)data[len-1]
					  ,displacement);
		break;
	 case 0x83:
		type=(data[1]>>3)&7;
		len=modrmbyte(&data[1],&type,&value,&displacement)+3;
		if((opadd)&&((type==INDIRECT)||(type==DISP8)||(type==DISP32)||(type==MEMLOC)))type+=2;
		else if((type==INDIRECT)||(type==DISP8)||(type==DISP32)||(type==MEMLOC))type+=3;
		if(data[len-1]<0x80)
		  addtoasm(ip,OP_ADD+((data[1]>>3)&7),len,data,type,value,IMM,(unsigned long)data[len-1]
					  ,displacement);
		else
		  addtoasm(ip,OP_ADD+((data[1]>>3)&7),len,data,type,value,IMM,0xffffff00+(unsigned long)data[len-1]
					  ,displacement);
		break;
	 case 0x84:
		len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_TEST,len,data,type,value,REG,REG_AL+((data[1]>>3)&7),displacement);
		break;
	 case 0x85:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_TEST,len,data,type,value,REG,REG_AX+((data[1]>>3)&7)+opadd,displacement);
		break;
	 case 0x86:
		len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_XCHG,len,data,type,value,REG,REG_AL+((data[1]>>3)&7),displacement);
		break;
	 case 0x87:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_XCHG,len,data,type,value,REG,REG_AX+((data[1]>>3)&7)+opadd,displacement);
		break;
	 case 0x88:
		len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_MOV,len,data,type,value,REG,REG_AL+((data[1]>>3)&7),displacement);
		break;
	 case 0x89:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_MOV,len,data,type,value,REG,REG_AX+((data[1]>>3)&7)+opadd,displacement);
		break;
	 case 0x8a:
		len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_MOV,len,data,REG,REG_AL+((data[1]>>3)&7),type,value,displacement);
		break;
	 case 0x8b:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_MOV,len,data,REG,REG_AX+((data[1]>>3)&7)+opadd,type,value,displacement);
		break;
	 case 0x8c:
		type=(data[1]>>3)&7;
		if((type==6)||(type==7))
		  addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
		else
		{ len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		  addtoasm(ip,OP_MOV,len,data,type,value,REG,REG_CS+((data[1]>>3)&7),displacement);
		}
		break;
	 case 0x8d:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_LEA,len,data,REG,REG_AX+((data[1]>>3)&7)+opadd,type,value,displacement);
		break;
	 case 0x8e:
		type=(data[1]>>3)&7;
		if((type==6)||(type==7))
		  addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
		else
		{ len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		  addtoasm(ip,OP_MOV,len,data,REG,REG_CS+((data[1]>>3)&7),type,value,displacement);
		}
		break;
	 case 0x8f:
		type=(data[1]>>3)&7;
		if(type)
		  addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
		else
		{ len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		  addtoasm(ip,OP_POP,len,data,type,value,0,0,displacement);
		}
		break;
	 case 0x90:
		addtoasm(ip,OP_NOP,len=1,data,0,0,0,0,0);
		break;
	 case 0x91:
	 case 0x92:
	 case 0x93:
	 case 0x94:
	 case 0x95:
	 case 0x96:
	 case 0x97:
		addtoasm(ip,OP_XCHG,len=1,data,REG,REG_AX+opadd,REG,data[0]-0x90+opadd,0);
		break;
	 case 0x98:
		if(operandprefix)
		  addtoasm(ip,OP_CBW,len=1,data,0,0,0,0,0);
		else
		  addtoasm(ip,OP_CWDE,len=1,data,0,0,0,0,0);
		break;
	 case 0x99:
		if(operandprefix)
		  addtoasm(ip,OP_CWD,len=1,data,0,0,0,0,0);
		else
		  addtoasm(ip,OP_CDQ,len=1,data,0,0,0,0,0);
		break;
	 case 0x9a:
		addtoasm(ip,OP_CALLF,len=5,data,MEM,(unsigned long)(data[1]),0,0,0);
		xr.addxref(lastasm->arg1,lastasm->addr,XREF_CALL);
		break;
	 case 0x9b:
		addtoasm(ip,OP_WAIT,len=1,data,0,0,0,0,0);
		break;
	 case 0x9c:
		addtoasm(ip,OP_PUSHF,len=1,data,0,0,0,0,0);
		break;
	 case 0x9d:
		addtoasm(ip,OP_POPF,len=1,data,0,0,0,0,0);
		break;
	 case 0x9e:
		addtoasm(ip,OP_SAHF,len=1,data,0,0,0,0,0);
		break;
	 case 0x9f:
		addtoasm(ip,OP_LAHF,len=1,data,0,0,0,0,0);
		break;
	 case 0xa0:
		if(addressprefix)
		  addtoasm(ip,OP_MOV,len=3,data,REG,REG_AL,MEMLOC,((unsigned long)(data[2]<<8)+data[1]),0);
		else
		  addtoasm(ip,OP_MOV,len=5,data,REG,REG_AL,MEMLOC,((unsigned long *)(&data[1]))[0],0);
		break;
	 case 0xa1:
		if(addressprefix)
		  addtoasm(ip,OP_MOV,len=3,data,REG,REG_AX+opadd,MEMLOC,((unsigned long)(data[2]<<8)+data[1]),0);
		else
		  addtoasm(ip,OP_MOV,len=5,data,REG,REG_AX+opadd,MEMLOC,((unsigned long *)(&data[1]))[0],0);
		break;
	 case 0xa2:
		if(addressprefix)
		  addtoasm(ip,OP_MOV,len=3,data,MEMLOC,((unsigned short *)(&data[1]))[0],REG,REG_AL,0);
		else
		  addtoasm(ip,OP_MOV,len=5,data,MEMLOC,((unsigned long *)(&data[1]))[0],REG,REG_AL,0);
		break;
	 case 0xa3:
		if(addressprefix)
		  addtoasm(ip,OP_MOV,len=3,data,MEMLOC,((unsigned short *)(&data[1]))[0],REG,REG_AX+opadd,0);
		else
		  addtoasm(ip,OP_MOV,len=5,data,MEMLOC,((unsigned long *)(&data[1]))[0],REG,REG_AX+opadd,0);
		break;
	 case 0xa4:
		addtoasm(ip,OP_MOVSB,len=1,data,0,0,0,0,0);
		break;
	 case 0xa5:
		if(operandprefix)
		  addtoasm(ip,OP_MOVSW,len=1,data,0,0,0,0,0);
		else
		  addtoasm(ip,OP_MOVSD,len=1,data,0,0,0,0,0);
		break;
	 case 0xa6:
		addtoasm(ip,OP_CMPSB,len=1,data,0,0,0,0,0);
		break;
	 case 0xa7:
		if(operandprefix)
		  addtoasm(ip,OP_CMPSW,len=1,data,0,0,0,0,0);
		else
		  addtoasm(ip,OP_CMPSD,len=1,data,0,0,0,0,0);
		break;
	 case 0xa8:
		addtoasm(ip,OP_TEST,len=2,data,REG,REG_AL,IMM,(unsigned long)data[1],0);
		break;
	 case 0xa9:
		if(opadd)
		  addtoasm(ip,OP_TEST,len=3,data,REG,REG_AX+opadd,IMM,(((unsigned long)data[2])<<8)+data[1],0);
		else
		  addtoasm(ip,OP_TEST,len=5,data,REG,REG_AX,IMM,((unsigned long *)(&data[1]))[0],0);
		break;
	 case 0xaa:
		addtoasm(ip,OP_STOSB,len=1,data,0,0,0,0,0);
		break;
	 case 0xab:
		if(operandprefix)
		  addtoasm(ip,OP_STOSW,len=1,data,0,0,0,0,0);
		else
		  addtoasm(ip,OP_STOSD,len=1,data,0,0,0,0,0);
		break;
	 case 0xac:
		addtoasm(ip,OP_LODSB,len=1,data,0,0,0,0,0);
		break;
	 case 0xad:
		if(operandprefix)
		  addtoasm(ip,OP_LODSW,len=1,data,0,0,0,0,0);
		else
		  addtoasm(ip,OP_LODSD,len=1,data,0,0,0,0,0);
		break;
	 case 0xae:
		addtoasm(ip,OP_SCASB,len=1,data,0,0,0,0,0);
		break;
	 case 0xaf:
		if(operandprefix)
		  addtoasm(ip,OP_SCASW,len=1,data,0,0,0,0,0);
		else
		  addtoasm(ip,OP_SCASD,len=1,data,0,0,0,0,0);
		break;
	 case 0xb0:
	 case 0xb1:
	 case 0xb2:
	 case 0xb3:
	 case 0xb4:
	 case 0xb5:
	 case 0xb6:
	 case 0xb7:
		addtoasm(ip,OP_MOV,len=2,data,REG,REG_AL+data[0]-0xb0,IMM,(unsigned long)(data[1]),0);
		break;
	 case 0xb8:
	 case 0xb9:
	 case 0xba:
	 case 0xbb:
	 case 0xbc:
	 case 0xbd:
	 case 0xbe:
	 case 0xbf:
		if(operandprefix)
		  addtoasm(ip,OP_MOV,len=3,data,REG,REG_AX+data[0]-0xb8+opadd,IMM,data[1]+(((unsigned long)data[2])<<8),0);
		else
		  addtoasm(ip,OP_MOV,len=5,data,REG,REG_AX+data[0]-0xb8,IMM,((unsigned long *)(&data[1]))[0],0);
		if(relocs.isreloc(ip+1))
		{ lastasm->arg2type=OFFSET;
		  xr.addxref(lastasm->arg1,lastasm->addr,XREF_DATA);
		}
		break;
	 case 0xc0:
		len=modrm8byte(&data[1],&type,&value,&displacement)+3;
		addtoasm(ip,OP_ROL+((data[1]>>3)&7),len,data,type,value,IMM,(unsigned long)data[len-1],displacement);
		break;
	 case 0xc1:
		len=modrmbyte(&data[1],&type,&value,&displacement)+3;
		addtoasm(ip,OP_ROL+((data[1]>>3)&7),len,data,type,value,IMM,(unsigned long)data[len-1],displacement);
		break;
	 case 0xc2:
		addtoasm(ip,OP_RETN,len=3,data,IMM,data[1]+(((unsigned long)data[2])<<8),0,0,0);
		break;
	 case 0xc3:
		addtoasm(ip,OP_RETN,len=1,data,0,0,0,0,0);
		break;
	 case 0xc4:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_LES,len,data,type,value,REG,REG_AX+((data[1]>>3)&7)+opadd,displacement);
		break;
	 case 0xc5:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_LDS,len,data,type,value,REG,REG_AX+((data[1]>>3)&7)+opadd,displacement);
		break;
	 case 0xc6:
		type=(data[1]>>3)&7;
		if(type)
		  addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
		else
		{ len=modrmbyte(&data[1],&type,&value,&displacement)+3;
		  if((type==INDIRECT)||(type==DISP8)||(type==DISP32)||(type==MEMLOC))type+=1;
		  addtoasm(ip,OP_MOV,len,data,type,value,IMM,(unsigned long )(data[len-1])
					  ,displacement);
		}
		break;
	 case 0xc7:
		type=(data[1]>>3)&7;
		if(type)
		  addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
		else
		{ if(operandprefix)
		  { len=modrmbyte(&data[1],&type,&value,&displacement)+4;
			 if((type==INDIRECT)||(type==DISP8)||(type==DISP32)||(type==MEMLOC))type+=2;
			 addtoasm(ip,OP_MOV,len,data,type,value,IMM,data[len-2]+(((unsigned long)data[len-1])<<8)
					  ,displacement);
		  }
		  else
		  { len=modrmbyte(&data[1],&type,&value,&displacement)+6;
			 if((type==INDIRECT)||(type==DISP8)||(type==DISP32)||(type==MEMLOC))type+=3;
			 addtoasm(ip,OP_MOV,len,data,type,value,IMM,((unsigned long *)(&data[len-4]))[0]
					  ,displacement);
			 if(relocs.isreloc(ip+len-4))
			 { lastasm->arg2type=OFFSET;
				xr.addxref(lastasm->arg1,lastasm->addr,XREF_DATA);
			 }
		  }
		}
		break;
	 case 0xc8:
		addtoasm(ip,OP_ENTER,len=4,data,IMM,data[1]+(((unsigned long)data[2])<<8),IMM,(unsigned long)data[3],0);
		break;
	 case 0xc9:
		addtoasm(ip,OP_LEAVE,len=1,data,0,0,0,0,0);
		break;
	 case 0xca:
		addtoasm(ip,OP_RETF,len=3,data,IMM,data[1]+(((unsigned long)data[2])<<8),0,0,0);
		break;
	 case 0xcb:
		addtoasm(ip,OP_RETF,len=1,data,0,0,0,0,0);
		break;
	 case 0xcc:
		addtoasm(ip,OP_INT,len=1,data,IMM,3,0,0,0);
		break;
	 case 0xcd:
		addtoasm(ip,OP_INT,len=2,data,IMM,(unsigned long)data[1],0,0,0);
		break;
	 case 0xce:
		addtoasm(ip,OP_INTO,len=1,data,0,0,0,0,0);
		break;
	 case 0xcf:
		addtoasm(ip,OP_IRET,len=1,data,0,0,0,0,0);
		break;
	 case 0xd0:
		len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_ROL+((data[1]>>3)&7),len,data,type,value,IMM,1,displacement);
		break;
	 case 0xd1:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_ROL+((data[1]>>3)&7),len,data,type,value,IMM,1,displacement);
		break;
	 case 0xd2:
		len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_ROL+((data[1]>>3)&7),len,data,type,value,REG,REG_CL,displacement);
		break;
	 case 0xd3:
		len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		addtoasm(ip,OP_ROL+((data[1]>>3)&7),len,data,type,value,REG,REG_CL,displacement);
		break;
	 case 0xd4:
		addtoasm(ip,OP_AAM,len=2,data,IMM,(unsigned long)data[1],0,0,0);
		break;
	 case 0xd5:
		addtoasm(ip,OP_AAD,len=2,data,IMM,(unsigned long)data[1],0,0,0);
		break;
	 case 0xd6:
		addtoasm(ip,OP_SETALC,len=1,data,0,0,0,0,0);
		break;
	 case 0xd7:
		addtoasm(ip,OP_XLAT,len=1,data,0,0,0,0,0);
		break;
	 case 0xd8:
		if(data[1]>0xbf)
		{ addtoasm(ip,OP_FPU,len=2,data,FREG,REG_ST0,FREG,REG_ST0+data[1]&7,0);
		  lastasm->thirdarg=FPU_FADD+((data[1]>>3)&7);
		}
		else
		{ len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		  // single real = dword
		  if((type==INDIRECT)||(type==DISP8)||(type==DISP32)||(type==MEMLOC))type+=3;
		  addtoasm(ip,OP_FPU,len,data,type,value,0,0,displacement);
		  lastasm->thirdarg=FPU_FADD+((data[1]>>3)&7);
		}
		break;
	 case 0xd9:
		if(data[1]>0xbf)
		{ if(((data[1]>>3)&7)==0)
		  { addtoasm(ip,OP_FPU,len=2,data,FREG,REG_ST0,FREG,REG_ST0+data[1]&7,0);
			 lastasm->thirdarg=FPU_FLD;
			 break;
		  }
		  else if(((data[1]>>3)&7)==1)
		  { addtoasm(ip,OP_FPU,len=2,data,FREG,REG_ST0,FREG,REG_ST0+data[1]&7,0);
			 lastasm->thirdarg=FPU_FXCH;
			 break;
		  }
		  else
		  { switch(data[1])
			 { case 0xd0:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FNOP;
				  break;
				case 0xe0:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FCHS;
				  break;
				case 0xe1:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FABS;
				  break;
				case 0xe4:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FTST;
				  break;
				case 0xe5:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FXAM;
				  break;
				case 0xe8:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FLD1;
				  break;
				case 0xe9:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FLDL2T;
				  break;
				case 0xea:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FLDL2E;
				  break;
				case 0xeb:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FLDPI;
				  break;
				case 0xec:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FLDLG2;
				  break;
				case 0xed:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FLDLN2;
				  break;
				case 0xee:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FLDZ;
				  break;
				case 0xf0:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_F2XM1;
				  break;
				case 0xf1:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FYL2X;
				  break;
				case 0xf2:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FPTAN;
				  break;
				case 0xf3:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FPATAN;
				  break;
				case 0xf4:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FXTRACT;
				  break;
				case 0xf5:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FPREM1;
				  break;
				case 0xf6:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FDECSTP;
				  break;
				case 0xf7:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FINCSTP;
				  break;
				case 0xf8:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FPREM;
				  break;
				case 0xf9:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FYL2XP1;
				  break;
				case 0xfa:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FSQRT;
				  break;
				case 0xfb:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FSINCOS;
				  break;
				case 0xfc:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FRNDINT;
				  break;
				case 0xfd:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FSCALE;
				  break;
				case 0xfe:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FSIN;
				  break;
				case 0xff:
				  addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FCOS;
				  break;
				default:
				  addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
				  break;
			 }
		  }
		}
		else
		{ type=(data[1]>>3)&7;
		  if(type==1)
			 addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
		  else
		  { len=modrmbyte(&data[1],&type,&value,&displacement)+2;
			 addtoasm(ip,OP_FPU,len,data,type,value,0,0,displacement);
			 switch((data[1]>>3)&7)
			 { case 0:
				  lastasm->arg1type+=3; // single real
				  lastasm->thirdarg=FPU_FLD;
				  break;
				case 2:
				  lastasm->arg1type+=3; // single real
				  lastasm->thirdarg=FPU_FST;
				  break;
				case 3:
				  lastasm->arg1type+=3; // single real
				  lastasm->thirdarg=FPU_FSTP;
				  break;
				case 4:
				  lastasm->thirdarg=FPU_FLDENV;   // 14/28 bytes ?
				  break;
				case 5:
				  lastasm->arg1type+=2; // 2 bytes
				  lastasm->thirdarg=FPU_FLDCW;
				  break;
				case 6:
				  lastasm->thirdarg=FPU_FSTENV;   // 14/28 bytes ?
				  break;
				case 7:
				  lastasm->arg1type+=2; // 2 bytes
				  lastasm->thirdarg=FPU_FSTCW;
				  break;
			 }
		  }
		}
		break;
	 case 0xda:
		if(data[1]>0xbf)
		{ switch((data[1]>>3)&7)
		  { case 0x00:
				addtoasm(ip,OP_FPU,len=2,data,FREG,REG_ST0,FREG,REG_ST0+data[1]&7,0);
				lastasm->thirdarg=FPU_FCMOVB;
				break;
			 case 0x01:
				addtoasm(ip,OP_FPU,len=2,data,FREG,REG_ST0,FREG,REG_ST0+data[1]&7,0);
				lastasm->thirdarg=FPU_FCMOVE;
				break;
			 case 0x02:
				addtoasm(ip,OP_FPU,len=2,data,FREG,REG_ST0,FREG,REG_ST0+data[1]&7,0);
				lastasm->thirdarg=FPU_FCMOVBE;
				break;
			 case 0x03:
				addtoasm(ip,OP_FPU,len=2,data,FREG,REG_ST0,FREG,REG_ST0+data[1]&7,0);
				lastasm->thirdarg=FPU_FCMOVU;
				break;
			 default:
				if(data[1]==0xe1)
				{ addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FUCOMPP;
				}
				else addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
				break;
		  }
		}
		else
		{ len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		  // short int
		  if((type==INDIRECT)||(type==DISP8)||(type==DISP32)||(type==MEMLOC))type+=3;
		  addtoasm(ip,OP_FPU,len,data,type,value,0,0,displacement);
		  lastasm->thirdarg=FPU_FIADD+((data[1]>>3)&7);
		}
		break;
	 case 0xdb:
		if(data[1]>0xbf)
		{ switch((data[1]>>3)&7)
		  { case 0x00:
				addtoasm(ip,OP_FPU,len=2,data,FREG,REG_ST0,FREG,REG_ST0+data[1]&7,0);
				lastasm->thirdarg=FPU_FCMOVNB;
				break;
			 case 0x01:
				addtoasm(ip,OP_FPU,len=2,data,FREG,REG_ST0,FREG,REG_ST0+data[1]&7,0);
				lastasm->thirdarg=FPU_FCMOVNE;
				break;
			 case 0x02:
				addtoasm(ip,OP_FPU,len=2,data,FREG,REG_ST0,FREG,REG_ST0+data[1]&7,0);
				lastasm->thirdarg=FPU_FCMOVNBE;
				break;
			 case 0x03:
				addtoasm(ip,OP_FPU,len=2,data,FREG,REG_ST0,FREG,REG_ST0+data[1]&7,0);
				lastasm->thirdarg=FPU_FCMOVNU;
				break;
			 case 0x05:
				addtoasm(ip,OP_FPU,len=2,data,FREG,REG_ST0,FREG,REG_ST0+data[1]&7,0);
				lastasm->thirdarg=FPU_FUCOMI;
				break;
			 case 0x06:
				addtoasm(ip,OP_FPU,len=2,data,FREG,REG_ST0,FREG,REG_ST0+data[1]&7,0);
				lastasm->thirdarg=FPU_FCOMI;
				break;
			 default:
				if(data[1]==0xe2)
				{ addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FCLEX;
				}
				else if(data[1]==0xe3)
				{ addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				  lastasm->thirdarg=FPU_FINIT;
				}
				else addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
				break;
		  }
		}
		else
		{ type=(data[1]>>3)&7;
		  if((type==1)||(type==4)||(type==6))
			 addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
		  else
		  { len=modrmbyte(&data[1],&type,&value,&displacement)+2;
			 // short int / extended real
			 if((type==INDIRECT)||(type==DISP8)||(type==DISP32)||(type==MEMLOC))
			 { if(((data[1]>>3)&7)>4)type+=5;
				else type+=3;
			 }
			 addtoasm(ip,OP_FPU,len,data,type,value,0,0,displacement);
			 lastasm->thirdarg=FPU_FILD+((data[1]>>3)&7);
		  }
		}
		break;
	 case 0xdc:
		if(data[1]>0xbf)
		{ if((((data[1]>>3)&7)==2)||(((data[1]>>3)&7)==3))
			 addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
		  else
		  { addtoasm(ip,OP_FPU,len=2,data,FREG,REG_ST0+data[1]&7,FREG,REG_ST0,0);
			 lastasm->thirdarg=FPU_FADD+((data[1]>>3)&7);
		  }
		}
		else
		{ len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		  // double real
		  if((type==INDIRECT)||(type==DISP8)||(type==DISP32)||(type==MEMLOC))type+=4;
		  addtoasm(ip,OP_FPU,len,data,type,value,0,0,displacement);
		  lastasm->thirdarg=FPU_FADD+((data[1]>>3)&7);
		}
		break;
	 case 0xdd:
		if(data[1]>0xbf)
		{ if((((data[1]>>3)&7)==1)||(((data[1]>>3)&7)==6)||(((data[1]>>3)&7)==7))
			 addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
		  else
		  { addtoasm(ip,OP_FPU,len=2,data,FREG,REG_ST0+data[1]&7,0,0,0);
			 switch((data[1]>>3)&7)
			 { case 0:
				  lastasm->thirdarg=FPU_FFREE;
				  break;
				case 2:
				  lastasm->thirdarg=FPU_FST;
				  break;
				case 3:
				  lastasm->thirdarg=FPU_FSTP;
				  break;
				case 4:
				  lastasm->thirdarg=FPU_FUCOM;
				  lastasm->arg2type=FREG;
				  lastasm->arg2=REG_ST0;
				  break;
				case 5:
				  lastasm->thirdarg=FPU_FUCOMP;
				  break;
			 }
		  }
		}
		else
		{ type=(data[1]>>3)&7;
		  if((type==1)||(type==5))
			 addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
		  else
		  { len=modrmbyte(&data[1],&type,&value,&displacement)+2;
			 addtoasm(ip,OP_FPU,len,data,type,value,0,0,displacement);
			 switch((data[1]>>3)&7)
			 { case 0:
				  lastasm->arg1type+=4;  // double real
				  lastasm->thirdarg=FPU_FLD;
				  break;
				case 2:
				  lastasm->arg1type+=4;  // double real
				  lastasm->thirdarg=FPU_FST;
				  break;
				case 3:
				  lastasm->arg1type+=4;  // double real
				  lastasm->thirdarg=FPU_FSTP;
				  break;
				case 4:
				  lastasm->thirdarg=FPU_FRSTOR;  // 98/108 bytes ?
				  break;
				case 6:
				  lastasm->thirdarg=FPU_FSAVE;   // 98/108 bytes ?
				  break;
				case 7:
				  lastasm->arg1type+=2;   // 2 bytes
				  lastasm->thirdarg=FPU_FSTSW;
				  break;
			 }
		  }
		}
		break;
	 case 0xde:
		if(data[1]>0xbf)
		{ if((((data[1]>>3)&7)==2)||(((data[1]>>3)&7)==3))
		  { if(data[1]==0xd9)
			 {	addtoasm(ip,OP_FPU,len=2,data,0,0,0,0,0);
				lastasm->thirdarg=FPU_FCOMPP;
			 }
			 else
				addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
		  }
		  else
		  { addtoasm(ip,OP_FPU,len=2,data,FREG,REG_ST0+data[1]&7,FREG,REG_ST0,0);
			 lastasm->thirdarg=FPU_FADDP+((data[1]>>3)&7);
		  }
		}
		else
		{ len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		  // word int
		  if((type==INDIRECT)||(type==DISP8)||(type==DISP32)||(type==MEMLOC))type+=2;
		  addtoasm(ip,OP_FPU,len,data,type,value,0,0,displacement);
		  lastasm->thirdarg=FPU_FIADD+((data[1]>>3)&7);
		}
		break;
	 case 0xdf:
		if(data[1]>0xbf)
		{ if((((data[1]>>3)&7)<4)||(((data[1]>>3)&7)==7)||((((data[1]>>3)&7)==4)&&(data[1]!=0xe0)))
			 addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
		  else
		  { addtoasm(ip,OP_FPU,len=2,data,FREG,REG_ST0,FREG,REG_ST0+data[1]&7,0);
			 switch((data[1]>>3)&7)
			 { case 4:
				  lastasm->arg1type=REG;
				  lastasm->arg1=REG_AX+8;
				  lastasm->arg2type=0;
				  lastasm->arg2=0;
				  lastasm->thirdarg=FPU_FSTSW;
				  break;
				case 5:
				  lastasm->thirdarg=FPU_FCOMIP;
				  break;
				case 6:
				  lastasm->thirdarg=FPU_FUCOMIP;
				  break;
			 }
		  }
		}
		else
		{ type=(data[1]>>3)&7;
		  if(type==1)
			 addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
		  else
		  { len=modrmbyte(&data[1],&type,&value,&displacement)+2;
			 addtoasm(ip,OP_FPU,len,data,type,value,0,0,displacement);
			 switch((data[1]>>3)&7)
			 { case 0:
				  lastasm->arg1type+=2;  // word integer
				  lastasm->thirdarg=FPU_FILD;
				  break;
				case 2:
				  lastasm->arg1type+=2;  // word integer
				  lastasm->thirdarg=FPU_FIST;
				  break;
				case 3:
				  lastasm->arg1type+=2;  // word integer
				  lastasm->thirdarg=FPU_FISTP;
				  break;
				case 4:
				  lastasm->arg1type+=5;  // bcd tbyte
				  lastasm->thirdarg=FPU_FBLD;
				  break;
				case 5:
				  lastasm->arg1type+=4;  // long integer
				  lastasm->thirdarg=FPU_FILD;
				  break;
				case 6:
				  lastasm->arg1type+=5;  // bcd tbyte
				  lastasm->thirdarg=FPU_FBSTP;
				  break;
				case 7:
				  lastasm->arg1type+=4;  // long integer
				  lastasm->thirdarg=FPU_FISTP;
				  break;
			 }
		  }
		}
		break;
	 case 0xe0:
		if(data[1]<0x80)
		  addtoasm(ip,OP_LOOPNZ,len=2,data,MEM,ip+(unsigned long)(data[1])+2,0,0,0);
		else
		  addtoasm(ip,OP_LOOPNZ,len=2,data,MEM,ip+(unsigned long)(data[1])+0xffffff00+2,0,0,0);
		xr.addxref(lastasm->arg1,lastasm->addr,XREF_JUMP);
		break;
	 case 0xe1:
		if(data[1]<0x80)
		  addtoasm(ip,OP_LOOPZ,len=2,data,MEM,ip+(unsigned long)(data[1])+2,0,0,0);
		else
		  addtoasm(ip,OP_LOOPZ,len=2,data,MEM,ip+(unsigned long)(data[1])+0xffffff00+2,0,0,0);
		xr.addxref(lastasm->arg1,lastasm->addr,XREF_JUMP);
		break;
	 case 0xe2:
		if(data[1]<0x80)
		  addtoasm(ip,OP_LOOP,len=2,data,MEM,ip+(unsigned long)(data[1])+2,0,0,0);
		else
		  addtoasm(ip,OP_LOOP,len=2,data,MEM,ip+(unsigned long)(data[1])+0xffffff00+2,0,0,0);
		xr.addxref(lastasm->arg1,lastasm->addr,XREF_JUMP);
		break;
	 case 0xe3:
		if(data[1]<0x80)
		  addtoasm(ip,OP_JECXZ,len=2,data,MEM,ip+(unsigned long)(data[1])+2,0,0,0);
		else
		  addtoasm(ip,OP_JECXZ,len=2,data,MEM,ip-(unsigned long)(data[1])+0xffffff00+2,0,0,0);
		xr.addxref(lastasm->arg1,lastasm->addr,XREF_JUMP);
		break;
	 case 0xe4:
		addtoasm(ip,OP_IN,len=2,data,REG,REG_AL,IMM,(unsigned long)data[1],0);
		break;
	 case 0xe5:
		addtoasm(ip,OP_IN,len=2,data,REG,REG_AX,IMM,(unsigned long)data[1],0);
		break;
	 case 0xe6:
		addtoasm(ip,OP_OUT,len=2,data,IMM,(unsigned long)data[1],REG,REG_AL,0);
		break;
	 case 0xe7:
		addtoasm(ip,OP_OUT,len=2,data,IMM,(unsigned long)data[1],REG,REG_AX,0);
		break;
	 case 0xe8:
		if(addressprefix)
		  addtoasm(ip,OP_CALL,len=3,data,MEM,ip+((unsigned short *)(&data[1]))[0]+3,0,0,0);
		else
		  addtoasm(ip,OP_CALL,len=5,data,MEM,ip+((unsigned long *)(&data[1]))[0]+5,0,0,0);
		xr.addxref(lastasm->arg1,lastasm->addr,XREF_CALL);
		break;
	 case 0xe9:
		if(addressprefix)
		  addtoasm(ip,OP_JMP,len=3,data,MEM,ip+((unsigned short *)(&data[1]))[0]+3,0,0,0);
		else
		  addtoasm(ip,OP_JMP,len=5,data,MEM,ip+((unsigned long *)(&data[1]))[0]+5,0,0,0);
		xr.addxref(lastasm->arg1,lastasm->addr,XREF_JUMP);
		break;
	 case 0xea:
		addtoasm(ip,OP_JMP,len=5,data,MEM,((unsigned long *)(&data[1]))[0],0,0,0);
		xr.addxref(lastasm->arg1,lastasm->addr,XREF_JUMP);
		break;
	 case 0xeb:
		if(data[1]<0x80)
		  addtoasm(ip,OP_JMP,len=2,data,MEM,ip+(unsigned long)(data[1])+2,0,0,0);
		else
		  addtoasm(ip,OP_JMP,len=2,data,MEM,ip+(unsigned long)(data[1])+0xffffff00+2,0,0,0);
      xr.addxref(lastasm->arg1,lastasm->addr,XREF_JUMP);
		break;
	 case 0xec:
		addtoasm(ip,OP_IN,len=1,data,REG,REG_AL,REG,REG_DX+8,0);
		break;
	 case 0xed:
		addtoasm(ip,OP_IN,len=1,data,REG,REG_AX,REG,REG_DX+8,0);
		break;
	 case 0xee:
		addtoasm(ip,OP_OUT,len=1,data,REG,REG_DX+8,REG,REG_AL,0);
		break;
	 case 0xef:
		addtoasm(ip,OP_OUT,len=1,data,REG,REG_DX+8,REG,REG_AX,0);
		break;
	 case 0xf0:
		addtoasm(ip,OP_LOCK,len=1,data,0,0,0,0,0);
		break;
	 case 0xf1:
		addtoasm(ip,OP_SMI,len=1,data,0,0,0,0,0);
		break;
	 case 0xf2:
		addtoasm(ip,OP_REPNZ,len=1,data,0,0,0,0,0);
		break;
	 case 0xf3:
		addtoasm(ip,OP_REP,len=1,data,0,0,0,0,0);
		break;
	 case 0xf4:
		addtoasm(ip,OP_HLT,len=1,data,0,0,0,0,0);
		break;
	 case 0xf5:
		addtoasm(ip,OP_CMC,len=1,data,0,0,0,0,0);
		break;
	 case 0xf6:
		type=(data[1]>>3)&7;
		if(type==1)
		  addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
		else
		{ len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		  switch((data[1]>>3)&7)
		  { case 0:
				len+=1;
				addtoasm(ip,OP_TEST,len,data,type,value,IMM,(unsigned long)data[len-1],displacement);
				break;
			 case 2:
				addtoasm(ip,OP_NOT,len,data,type,value,0,0,displacement);
				break;
			 case 3:
				addtoasm(ip,OP_NEG,len,data,type,value,0,0,displacement);
				break;
			 case 4:
				addtoasm(ip,OP_MUL,len,data,type,value,0,0,displacement);
				break;
			 case 5:
				addtoasm(ip,OP_IMUL1,len,data,type,value,0,0,displacement);
				break;
			 case 6:
				addtoasm(ip,OP_DIV,len,data,type,value,0,0,displacement);
				break;
			 case 7:
				addtoasm(ip,OP_IDIV,len,data,type,value,0,0,displacement);
				break;
		  }
		}
		break;
	 case 0xf7:
		type=(data[1]>>3)&7;
		if(type==1)
		  addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
		else
		{ len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		  switch((data[1]>>3)&7)
		  { case 0:
				if(opadd)
				{ len+=2;
				  addtoasm(ip,OP_TEST,len,data,type,value,IMM,((unsigned long)(data[len-1])<<8)+data[len-2]
					 ,displacement);
				}
				else
				{ len+=4;
				  addtoasm(ip,OP_TEST,len,data,type,value,IMM,((unsigned long *)(&data[len-4]))[0],displacement);
				}
				break;
			 case 2:
				addtoasm(ip,OP_NOT,len,data,type,value,0,0,displacement);
				break;
			 case 3:
				addtoasm(ip,OP_NEG,len,data,type,value,0,0,displacement);
				break;
			 case 4:
				addtoasm(ip,OP_MUL,len,data,type,value,0,0,displacement);
				break;
			 case 5:
				addtoasm(ip,OP_IMUL1,len,data,type,value,0,0,displacement);
				break;
			 case 6:
				addtoasm(ip,OP_DIV,len,data,type,value,0,0,displacement);
				break;
			 case 7:
				addtoasm(ip,OP_IDIV,len,data,type,value,0,0,displacement);
				break;
		  }
		}
		break;
	 case 0xf8:
		addtoasm(ip,OP_CLC,len=1,data,0,0,0,0,0);
		break;
	 case 0xf9:
		addtoasm(ip,OP_STC,len=1,data,0,0,0,0,0);
		break;
	 case 0xfa:
		addtoasm(ip,OP_CLI,len=1,data,0,0,0,0,0);
		break;
	 case 0xfb:
		addtoasm(ip,OP_STI,len=1,data,0,0,0,0,0);
		break;
	 case 0xfc:
		addtoasm(ip,OP_CLD,len=1,data,0,0,0,0,0);
		break;
	 case 0xfd:
		addtoasm(ip,OP_STD,len=1,data,0,0,0,0,0);
		break;
	 case 0xfe:
		type=(data[1]>>3)&7;
		if(type>1)
		  addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
		else
		{ len=modrm8byte(&data[1],&type,&value,&displacement)+2;
		  switch((data[1]>>3)&7)
		  { case 0:
				addtoasm(ip,OP_INC,len,data,type,value,0,0,displacement);
				break;
			 case 1:
				addtoasm(ip,OP_DEC,len,data,type,value,0,0,displacement);
				break;
		  }
		}
		break;
	 case 0xff:
		type=(data[1]>>3)&7;
		if(type==7)
		  addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
		else
		{ len=modrmbyte(&data[1],&type,&value,&displacement)+2;
		  if((type==INDIRECT)||(type==DISP8)||(type==DISP32)||(type==MEMLOC))type+=3;
		  switch((data[1]>>3)&7)
		  { case 0:
				addtoasm(ip,OP_INC,len,data,type,value,0,0,displacement);
				break;
			 case 1:
				addtoasm(ip,OP_DEC,len,data,type,value,0,0,displacement);
				break;
			 case 2:
				addtoasm(ip,OP_CALL,len,data,type,value,0,0,displacement);
				break;
			 case 3:
				addtoasm(ip,OP_CALLF,len,data,type,value,0,0,displacement);
				break;
			 case 4:
				addtoasm(ip,OP_JMP,len,data,type,value,0,0,displacement);
				break;
			 case 5:
				addtoasm(ip,OP_JMP,len,data,type,value,0,0,displacement);
				break;
			 case 6:
				addtoasm(ip,OP_PUSH,len,data,type,value,0,0,displacement);
				break;
		  }
		}
		break;
	 default:
		addtoasm(ip,OP_DB,len=1,data,0,0,0,0,0);
		break;
  }
  if(!mode32)
  { operandprefix=!operandprefix;
	 addressprefix=!addressprefix;
  }
  return len;
}

void disasm::dumpasm(void)
{ struct asmlist *asmptr=disassembly;
  unsigned char bytes;
  BOOL toomanybytes;
  dis_comments.resetiterator();
  while(asmptr!=NULL)
  { if(KillThread)return;
	 xr.printxref(asmptr->addr);
	 if(exports.isexport(asmptr->addr))
	 { if(mode32)PrintBuff("%lx ",asmptr->addr);
      else PrintBuff("seg%03lx:%lx   ",asmptr->addr>>16,asmptr->addr&0xffff);
		exports.printname(asmptr->addr);
      LastPrintBuff(":");
	 }
	 if(mode32)PrintBuff("%lx   ",asmptr->addr);
	 else PrintBuff("seg%03lx:%lx   ",asmptr->addr>>16,asmptr->addr&0xffff);
	 bytes=asmptr->bytelength;
	 prefix=asmptr->segprefix;
	 lastsib=asmptr->sib;
	 toomanybytes=FALSE;
	 if(bytes>10)
	 { toomanybytes=TRUE;
		bytes=9;
	 }
	 while(bytes)
	 { LastPrintBuff("%02lx",(unsigned long)asmptr->data[asmptr->bytelength-bytes]);
		bytes--;
	 }
	 if(toomanybytes)LastPrintBuff("..");
	 LastPrintBuffEpos(30);
	 switch(asmptr->opcode)
	 { case OP_PUSH:
		  LastPrintBuff("push");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_POP:
		  LastPrintBuff("pop");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_NOT:
		  LastPrintBuff("not");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_NEG:
		  LastPrintBuff("neg");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_MUL:
		  LastPrintBuff("mul");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_IMUL1:
		  LastPrintBuff("imul");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_DIV:
		  LastPrintBuff("div");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_IDIV:
		  LastPrintBuff("idiv");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_CALL:
		  LastPrintBuff("call");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_CALLF:
		  LastPrintBuff("callf");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_LOOPNZ:
		  LastPrintBuff("loopnz");
		  PrintArg(asmptr->arg1type,asmptr->arg1,0);
		  break;
		case OP_LOOPZ:
		  LastPrintBuff("loopz");
		  PrintArg(asmptr->arg1type,asmptr->arg1,0);
		  break;
		case OP_LOOP:
		  LastPrintBuff("loop");
		  PrintArg(asmptr->arg1type,asmptr->arg1,0);
		  break;
		case OP_JECXZ:
		  LastPrintBuff("jecxz");
		  PrintArg(asmptr->arg1type,asmptr->arg1,0);
		  break;
		case OP_DD:
		  LastPrintBuff("dd");
		  PrintArg(asmptr->arg1type,asmptr->arg1,0);
		  break;
		case OP_DW:
		  LastPrintBuff("dw");
		  PrintArg(asmptr->arg1type,asmptr->arg1,0);
		  break;
		case OP_DS:
		  LastPrintBuff("ds");
        sarg=asmptr->data;
		  PrintArg(asmptr->arg1type,asmptr->arg1,0);
		  break;
		case OP_JMP:
		  LastPrintBuff("jmp");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_INC:
		  LastPrintBuff("inc");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_BSWAP:
		  LastPrintBuff("bswap");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_DEC:
		  LastPrintBuff("dec");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_SLDT:
		  LastPrintBuff("sldt");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_STR:
		  LastPrintBuff("str");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_LLDT:
		  LastPrintBuff("lldt");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_LTR:
		  LastPrintBuff("ltr");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_VERR:
		  LastPrintBuff("verr");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_VERW:
		  LastPrintBuff("verw");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_SGDT:
		  LastPrintBuff("sgdt");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_SIDT:
		  LastPrintBuff("sidt");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_LGDT:
		  LastPrintBuff("lgdt");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_LIDT:
		  LastPrintBuff("lidt");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_SMSW:
		  LastPrintBuff("smsw");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_LMSW:
		  LastPrintBuff("lmsw");
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_INT:
		  LastPrintBuff("int");
		  PrintArg(asmptr->arg1type,asmptr->arg1,0);
		  break;
		case OP_AAM:
		  LastPrintBuff("aam");
		  PrintArg(asmptr->arg1type,asmptr->arg1,0);
		  break;
		case OP_AAD:
		  LastPrintBuff("aad");
		  PrintArg(asmptr->arg1type,asmptr->arg1,0);
		  break;
		case OP_CMPXCH8B:
		  LastPrintBuff("cmpxch8b");
		  PrintArg(asmptr->arg1type,asmptr->arg1,0);
		  break;
		case OP_ADD:
		  LastPrintBuff("add");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_ROL:
		  LastPrintBuff("rol");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_ROR:
		  LastPrintBuff("ror");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_RCL:
		  LastPrintBuff("rcl");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_RCR:
		  LastPrintBuff("rcr");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_SHL:
		  LastPrintBuff("shl");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_SHR:
		  LastPrintBuff("shr");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_SAL:
		  LastPrintBuff("sal");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_SAR:
		  LastPrintBuff("sar");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_OR:
		  LastPrintBuff("or");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_ADC:
		  LastPrintBuff("adc");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_BSF:
		  LastPrintBuff("bsf");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_BSR:
		  LastPrintBuff("bsr");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_BT:
		  LastPrintBuff("bt");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_BTC:
		  LastPrintBuff("btc");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_BTR:
		  LastPrintBuff("btr");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_BTS:
		  LastPrintBuff("bts");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_SBB:
		  LastPrintBuff("sbb");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_AND:
		  LastPrintBuff("and");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_XADD:
		  LastPrintBuff("xadd");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_CMPXCH:
		  LastPrintBuff("cmpxch");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_IN:
		  LastPrintBuff("in");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_OUT:
		  LastPrintBuff("out");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_SUB:
		  LastPrintBuff("sub");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_XOR:
		  LastPrintBuff("xor");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_LAR:
		  LastPrintBuff("lar");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_LSL:
		  LastPrintBuff("lsl");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_CMP:
		  LastPrintBuff("cmp");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_MOV:
		  LastPrintBuff("mov");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_ARPL:
		  LastPrintBuff("arpl");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_MOVZX:
		  LastPrintBuff("movzx");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_MOVSX:
		  LastPrintBuff("movsx");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_LEA:
		  LastPrintBuff("lea");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_LES:
		  LastPrintBuff("les");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_LDS:
		  LastPrintBuff("lds");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_LSS:
		  LastPrintBuff("lss");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_LGS:
		  LastPrintBuff("lgs");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_LFS:
		  LastPrintBuff("lfs");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_ENTER:
		  LastPrintBuff("enter");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_TEST:
		  LastPrintBuff("test");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_BOUND:
		  LastPrintBuff("bound");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_XCHG:
		  LastPrintBuff("xchg");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_IMUL:
		  LastPrintBuff("imul");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  LastPrintBuff(", ");
		  PrintArg(IMM,asmptr->thirdarg,0);
		  break;
		case OP_SHLDI:
		  LastPrintBuff("shld");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  LastPrintBuff(", ");
		  PrintArg(IMM,asmptr->thirdarg,0);
		  break;
		case OP_SHLDCL:
		  LastPrintBuff("shld");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  LastPrintBuff(", cl");
		  break;
		case OP_SHRDCL:
		  LastPrintBuff("shrd");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  LastPrintBuff(", cl");
		  break;
		case OP_SHRDI:
		  LastPrintBuff("shrd");
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  LastPrintBuff(", ");
		  PrintArg(IMM,asmptr->thirdarg,0);
		  break;
		case OP_POPA:
		  LastPrintBuff("popa");
		  break;
		case OP_PUSHA:
		  LastPrintBuff("pusha");
		  break;
		case OP_NOP:
		  LastPrintBuff("nop");
		  break;
		case OP_CBW:
		  LastPrintBuff("cbw");
		  break;
		case OP_CWD:
		  LastPrintBuff("cwd");
		  break;
		case OP_CWDE:
		  LastPrintBuff("cwde");
		  break;
		case OP_CDQ:
		  LastPrintBuff("cdq");
		  break;
		case OP_INVLPG:
		  LastPrintBuff("invlpg");
		  break;
		case OP_INSB:
		  LastPrintBuff("insb");
		  break;
		case OP_INVD:
		  LastPrintBuff("invd");
		  break;
		case OP_WBINVD:
		  LastPrintBuff("wbinvd");
		  break;
		case OP_INSD:
		  LastPrintBuff("insd");
		  break;
		case OP_INSW:
		  LastPrintBuff("insw");
		  break;
		case OP_OUTSW:
		  LastPrintBuff("outsw");
		  break;
		case OP_OUTSB:
		  LastPrintBuff("outsb");
		  break;
		case OP_OUTSD:
		  LastPrintBuff("outsd");
		  break;
		case OP_WAIT:
		  LastPrintBuff("wait");
		  break;
		case OP_PUSHF:
		  LastPrintBuff("pushf");
		  break;
		case OP_POPF:
		  LastPrintBuff("popf");
		  break;
		case OP_SAHF:
		  LastPrintBuff("sahf");
		  break;
		case OP_LAHF:
		  LastPrintBuff("lahf");
		  break;
		case OP_MOVSB:
		  LastPrintBuff("movsb");
		  break;
		case OP_MOVSD:
		  LastPrintBuff("movsd");
		  break;
		case OP_CMPSB:
		  LastPrintBuff("cmpsb");
		  break;
		case OP_MOVSW:
		  LastPrintBuff("movsw");
		  break;
		case OP_CMPSW:
		  LastPrintBuff("cmpsw");
		  break;
		case OP_CMPSD:
		  LastPrintBuff("cmpsd");
		  break;
		case OP_STOSB:
		  LastPrintBuff("stosb");
		  break;
		case OP_STOSD:
		  LastPrintBuff("stosd");
		  break;
		case OP_LODSB:
		  LastPrintBuff("lodsb");
		  break;
		case OP_STOSW:
		  LastPrintBuff("stosw");
		  break;
		case OP_LODSW:
		  LastPrintBuff("lodsw");
		  break;
		case OP_LODSD:
		  LastPrintBuff("lodsd");
		  break;
		case OP_SCASB:
		  LastPrintBuff("scasb");
		  break;
		case OP_SCASW:
		  LastPrintBuff("scasw");
		  break;
		case OP_SCASD:
		  LastPrintBuff("scasd");
		  break;
		case OP_DAA:
		  LastPrintBuff("daa");
		  break;
		case OP_DAS:
		  LastPrintBuff("das");
		  break;
		case OP_AAA:
		  LastPrintBuff("aaa");
		  break;
		case OP_AAS:
		  LastPrintBuff("aas");
		  break;
		case OP_RETN:
		  LastPrintBuff("retn");
		  PrintArg(asmptr->arg1type,asmptr->arg1,0);
		  break;
		case OP_LEAVE:
		  LastPrintBuff("leave");
		  break;
		case OP_RETF:
		  LastPrintBuff("retf");
		  PrintArg(asmptr->arg1type,asmptr->arg1,0);
		  break;
		case OP_INTO:
		  LastPrintBuff("into");
		  break;
		case OP_IRET:
		  LastPrintBuff("iret");
		  break;
		case OP_ZEROBLOCK:
		  LastPrintBuff("db zeroblock");
        break;
		case OP_SETALC:
		  LastPrintBuff("setalc");
		  break;
		case OP_XLAT:
		  LastPrintBuff("xlat");
		  break;
		case OP_SMI:
		  LastPrintBuff("smi");
		  break;
		case OP_HLT:
		  LastPrintBuff("hlt");
		  break;
		case OP_CLTS:
		  LastPrintBuff("clts");
		  break;
		case OP_CMC:
		  LastPrintBuff("cmc");
		  break;
		case OP_CPUID:
		  LastPrintBuff("cpuid");
		  break;
		case OP_WRMSR:
		  LastPrintBuff("wrmsr");
		  break;
		case OP_RDTSC:
		  LastPrintBuff("rdtsc");
		  break;
		case OP_RDMSR:
		  LastPrintBuff("rdmsr");
		  break;
		case OP_RDPMC:
		  LastPrintBuff("rdpmc");
		  break;
		case OP_CLC:
		  LastPrintBuff("clc");
		  break;
		case OP_UD2:
		  LastPrintBuff("ud2");
		  break;
		case OP_RSM:
		  LastPrintBuff("rsm");
		  break;
		case OP_STC:
		  LastPrintBuff("stc");
		  break;
		case OP_CLI:
		  LastPrintBuff("cli");
		  break;
		case OP_STI:
		  LastPrintBuff("sti");
		  break;
		case OP_CLD:
		  LastPrintBuff("cld");
		  break;
		case OP_STD:
		  LastPrintBuff("std");
        break;
		case OP_DB:
		  LastPrintBuff("db %02lx",(unsigned long)asmptr->data[0]);
		  break;
		case OP_JO:
		case OP_JNO:
		case OP_JC:
		case OP_JNC:
		case OP_JZ:
		case OP_JNZ:
		case OP_JBE:
		case OP_JA:
		case OP_JS:
		case OP_JNS:
		case OP_JPE:
		case OP_JPO:
		case OP_JL:
		case OP_JGE:
		case OP_JLE:
		case OP_JG:
		  LastPrintBuff("%s",jtable[asmptr->opcode-OP_JO]);
		  PrintArg(asmptr->arg1type,asmptr->arg1,0);
		  break;
		case OP_SETO:
		case OP_SETNO:
		case OP_SETC:
		case OP_SETNC:
		case OP_SETZ:
		case OP_SETNZ:
		case OP_SETBE:
		case OP_SETA:
		case OP_SETS:
		case OP_SETNS:
		case OP_SETPE:
		case OP_SETPO:
		case OP_SETL:
		case OP_SETGE:
		case OP_SETLE:
		case OP_SETG:
		  LastPrintBuff("%s",stable[asmptr->opcode-OP_SETO]);
		  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
		  break;
		case OP_CMOVO:
		case OP_CMOVNO:
		case OP_CMOVC:
		case OP_CMOVNC:
		case OP_CMOVZ:
		case OP_CMOVNZ:
		case OP_CMOVBE:
		case OP_CMOVA:
		case OP_CMOVS:
		case OP_CMOVNS:
		case OP_CMOVPE:
		case OP_CMOVPO:
		case OP_CMOVL:
		case OP_CMOVGE:
		case OP_CMOVLE:
		case OP_CMOVG:
		  LastPrintBuff("%s",ctable[asmptr->opcode-OP_CMOVO]);
		  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
		  break;
		case OP_REPNZ:
		  LastPrintBuff("repnz:");
		  break;
		case OP_REP:
		  LastPrintBuff("rep:");
		  break;
		case OP_LOCK:
		  LastPrintBuff("lock:");
		  break;
		case OP_MMX:
		  switch(asmptr->thirdarg)
		  { case MMX_EMMS:
				LastPrintBuff("emms");
            break;
			 case MMX_PUNPCKL:
				LastPrintBuff("punpckl");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 case MMX_PUNPCKH:
				LastPrintBuff("punpckh");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 case MMX_PSRL:
				LastPrintBuff("psrl");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 case MMX_PACKSS:
				LastPrintBuff("packss");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 case MMX_PACKUS:
				LastPrintBuff("packus");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 case MMX_PCMPGT:
				LastPrintBuff("pcmpgt");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 case MMX_MOVD:
				LastPrintBuff("movd");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 case MMX_MOVQ:
				LastPrintBuff("movq");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 case MMX_PCMPEQ:
				LastPrintBuff("cmpeq");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 case MMX_PSRA:
				LastPrintBuff("psra");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 case MMX_PSLL:
				LastPrintBuff("psll");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 case MMX_PMULL:
				LastPrintBuff("pmull");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 case MMX_PMULH:
				LastPrintBuff("pmulh");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 case MMX_PMADD:
				LastPrintBuff("pmadd");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 case MMX_PSUBUS:
				LastPrintBuff("psubus");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 case MMX_PSUBS:
				LastPrintBuff("psubs");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 case MMX_PSUB:
				LastPrintBuff("psub");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 case MMX_PADDUS:
				LastPrintBuff("paddus");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 case MMX_PADDS:
				LastPrintBuff("padds");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 case MMX_PAND:
				LastPrintBuff("pand");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 case MMX_POR:
				LastPrintBuff("por");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 case MMX_PANDN:
				LastPrintBuff("pandn");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 case MMX_PXOR:
				LastPrintBuff("pxor");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 case MMX_PADD:
				LastPrintBuff("padd");
				PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				break;
			 default:
				break;
		  }
		  break;
		case OP_FPU:
		  switch(asmptr->thirdarg)
		  { case FPU_FADD:
				LastPrintBuff("fadd");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FMUL:
				LastPrintBuff("fmul");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FCOM:
				LastPrintBuff("fcom");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FCOMP:
				LastPrintBuff("fcomp");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FSUB:
				LastPrintBuff("fsub");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FSUBR:
				LastPrintBuff("fsubr");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FDIV:
				LastPrintBuff("fdiv");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FDIVR:
				LastPrintBuff("fdivr");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FIADD:
				LastPrintBuff("fiadd");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FIMUL:
				LastPrintBuff("fimul");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FICOM:
				LastPrintBuff("ficom");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FICOMP:
				LastPrintBuff("ficomp");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FISUB:
				LastPrintBuff("fisub");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FISUBR:
				LastPrintBuff("fisubr");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FIDIV:
				LastPrintBuff("fidiv");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FIDIVR:
				LastPrintBuff("fidivr");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FCMOVB:
				LastPrintBuff("fcmovb");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FCMOVBE:
				LastPrintBuff("fcmovbe");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FCMOVE:
				LastPrintBuff("fcmove");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FCMOVU:
				LastPrintBuff("fcmovu");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FADDP:
				LastPrintBuff("faddp");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FMULP:
				LastPrintBuff("fmulp");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FSUBRP:
				LastPrintBuff("fsubrp");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FSUBP:
				LastPrintBuff("fsubp");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FDIVRP:
				LastPrintBuff("fdivrp");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FDIVP:
				LastPrintBuff("fdivp");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FILD:
				LastPrintBuff("fild");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FIST:
				LastPrintBuff("fist");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FISTP:
				LastPrintBuff("fistp");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FLD:
				LastPrintBuff("fld");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FSTP:
				LastPrintBuff("fstp");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FCMOVNB:
				LastPrintBuff("fcmovnb");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FCMOVNE:
				LastPrintBuff("fcmovne");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FCMOVNBE:
				LastPrintBuff("fcmovnbe");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FCMOVNU:
				LastPrintBuff("fcmovnu");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FCOMI:
				LastPrintBuff("fcomi");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FUCOMI:
				LastPrintBuff("fucomi");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FST:
				LastPrintBuff("fst");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FLDENV:
				LastPrintBuff("fldenv");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FLDCW:
				LastPrintBuff("fldcw");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FSTENV:
				LastPrintBuff("fstenv");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FSTCW:
				LastPrintBuff("fstcw");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FXCH:
				LastPrintBuff("fxch");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FFREE:
				LastPrintBuff("ffree");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FUCOM:
				LastPrintBuff("fucom");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FUCOMP:
				LastPrintBuff("fucomp");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FBLD:
				LastPrintBuff("fbld");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FBSTP:
				LastPrintBuff("fbstp");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FSTSW:
				LastPrintBuff("fstsw");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FCOMIP:
				LastPrintBuff("fcomip");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FUCOMIP:
				LastPrintBuff("fucomip");
				if(asmptr->arg2type)
				  PrintArgs(asmptr->arg1type,asmptr->arg1,asmptr->arg2type,asmptr->arg2,asmptr->displacement);
				else
				  PrintArg(asmptr->arg1type,asmptr->arg1,asmptr->displacement);
				break;
			 case FPU_FUCOMPP:
				LastPrintBuff("fucompp");
				break;
			 case FPU_FRSTOR:
				LastPrintBuff("frstor");
				break;
			 case FPU_FSAVE:
				LastPrintBuff("fsave");
				break;
			 case FPU_FCOMPP:
				LastPrintBuff("fcompp");
				break;
			 case FPU_FCLEX:
				LastPrintBuff("fclex");
				break;
			 case FPU_FINIT:
				LastPrintBuff("finit");
				break;
			 case FPU_FNOP:
				LastPrintBuff("fnop");
				break;
			 case FPU_FCHS:
				LastPrintBuff("fchs");
				break;
			 case FPU_FABS:
				LastPrintBuff("fabs");
				break;
			 case FPU_FTST:
				LastPrintBuff("ftst");
				break;
			 case FPU_FXAM:
				LastPrintBuff("fxam");
				break;
			 case FPU_FLD1:
				LastPrintBuff("fld1");
				break;
			 case FPU_FLDL2T:
				LastPrintBuff("fldl2t");
				break;
			 case FPU_FLDL2E:
				LastPrintBuff("fldl2e");
				break;
			 case FPU_FLDPI:
				LastPrintBuff("fldpi");
				break;
			 case FPU_FLDLG2:
				LastPrintBuff("fldlg2");
				break;
			 case FPU_FLDLN2:
				LastPrintBuff("fldln2");
				break;
			 case FPU_FLDZ:
				LastPrintBuff("fldz");
				break;
			 case FPU_F2XM1:
				LastPrintBuff("f2xm1");
				break;
			 case FPU_FYL2X:
				LastPrintBuff("fyl2x");
				break;
			 case FPU_FPTAN:
				LastPrintBuff("fptan");
				break;
			 case FPU_FPATAN:
				LastPrintBuff("fpatan");
				break;
			 case FPU_FXTRACT:
				LastPrintBuff("fxtract");
				break;
			 case FPU_FPREM1:
				LastPrintBuff("fprem1");
				break;
			 case FPU_FDECSTP:
				LastPrintBuff("fdecstp");
				break;
			 case FPU_FINCSTP:
				LastPrintBuff("fincstp");
				break;
			 case FPU_FPREM:
				LastPrintBuff("fprem");
				break;
			 case FPU_FYL2XP1:
				LastPrintBuff("fyl2xp1");
				break;
			 case FPU_FSQRT:
				LastPrintBuff("fsqrt");
				break;
			 case FPU_FSINCOS:
				LastPrintBuff("fsincos");
				break;
			 case FPU_FRNDINT:
				LastPrintBuff("frndint");
				break;
			 case FPU_FSCALE:
				LastPrintBuff("fscale");
				break;
			 case FPU_FSIN:
				LastPrintBuff("fsin");
				break;
			 case FPU_FCOS:
				LastPrintBuff("fcos");
				break;
			 default:
				break;
		  }
		default:
		  break;
	 }
	 dis_comments.printcomment(asmptr->addr);
	 asmptr=asmptr->next;
  }
}

void disasm::addtoasm(unsigned long address,unsigned char op,unsigned int len,
  unsigned char *data,unsigned char arg1type,unsigned long arg1,unsigned char arg2type,
  unsigned long arg2,unsigned long disp)
{ struct asmlist *addit,*prev,*nxt,*destroy;
  address-=codeplus;
  len+=codeplus;
  data-=codeplus;
  if(disassembly==NULL)
  { disassembly=new struct asmlist;
	 addit=disassembly;
	 addit->next=NULL;
	 addit->last=NULL;
  }
  else
  { addit=disassembly;
	 if(lastasm!=NULL)
		if(address>lastasm->addr)addit=lastasm;
	 while((address>addit->addr)&&(addit->next!=NULL))addit=addit->next;
	 if(address<=addit->addr)
	 { prev=addit->last;
		nxt=addit;
		if(address+len<=addit->addr)
		{ nxt->last=new struct asmlist;
		  addit=nxt->last;
		  if(prev!=NULL)prev->next=addit;
		  addit->last=prev;
		  addit->next=nxt;
		}
	 }
	 else
	 { prev=addit;
		nxt=NULL;
		prev->next=new struct asmlist;
		addit=prev->next;
		addit->last=prev;
		addit->next=nxt;
	 }
  }
  if(disassembly->last!=NULL)disassembly=disassembly->last;
  addit->opcode=op;
  addit->addr=address;
  addit->bytelength=len;
  addit->data=data;
  addit->arg1type=arg1type;
  addit->arg1=arg1;
  addit->arg2type=arg2type;
  addit->arg2=arg2;
  addit->displacement=disp;
  addit->segprefix=0;
  addit->sib=lastsib;
  lastasm=addit;
  instct++;
  while(addit->next!=NULL)
  { if(addit->addr+addit->bytelength>addit->next->addr)
	 { destroy=addit->next;
		addit->next=destroy->next;
		if(destroy->next!=NULL)destroy->next->last=addit;
		delete destroy;
      instct--;
	 }
	 else break;
  }
  addit=lastasm;
  while(addit->last!=NULL)
  { if(addit->last->addr+addit->last->bytelength>addit->addr)
	 { destroy=addit->last;
		addit->last=destroy->last;
		if(destroy->last!=NULL)destroy->last->next=lastasm;
      else disassembly=lastasm;
		delete destroy;
		instct--;
	 }
	 else break;
  }
}

void disasm::PrintArgs(unsigned char arg1type,unsigned long arg1,
						 unsigned char arg2type,unsigned long arg2,unsigned long disp)
{ PrintArg(arg1type,arg1,disp);
  LastPrintBuff(",");
  PrintArg(arg2type,arg2,disp);
}

void disasm::PrintArg(unsigned char argtype,unsigned long arg,unsigned long disp)
{ if(!argtype)return;
  LastPrintBuff(" ");
  if((argtype==DISP8B)||(argtype==DISP32B)||(argtype==INDIRECTB)||(argtype==MEMLOCB))
	 LastPrintBuff("byte ptr ");
  if((argtype==DISP8W)||(argtype==DISP32W)||(argtype==INDIRECTW)||(argtype==MEMLOCW))
	 LastPrintBuff("word ptr ");
  if((argtype==DISP8D)||(argtype==DISP32D)||(argtype==INDIRECTD)||(argtype==MEMLOCD))
	 LastPrintBuff("dword ptr ");
  if((argtype==DISP8Q)||(argtype==DISP32Q)||(argtype==INDIRECTQ)||(argtype==MEMLOCQ))
	 LastPrintBuff("qword ptr ");
  if((argtype==DISP8T)||(argtype==DISP32T)||(argtype==INDIRECTT)||(argtype==MEMLOCT))
	 LastPrintBuff("tbyte ptr ");
  switch(argtype)
  { case REG:
		LastPrintBuff("%s",(unsigned char *)regtable[arg]);
		break;
	 case FREG:
		LastPrintBuff("%s",(unsigned char *)ftable[arg]);
		break;
	 case INDIRECT:
	 case INDIRECTB:
	 case INDIRECTW:
	 case INDIRECTD:
	 case INDIRECTQ:
	 case INDIRECTT:
		if(prefix)LastPrintBuff("%s:",(unsigned char *)regtable[prefix]);
		LastPrintBuff("[");
		PrintSib();
		LastPrintBuff("%s]",(unsigned char *)regtable[arg]);
		break;
	 case DISP32:
	 case DISP32B:
	 case DISP32W:
	 case DISP32D:
	 case DISP32Q:
	 case DISP32T:
		if(prefix)LastPrintBuff("%s:",(unsigned char *)regtable[prefix]);
		LastPrintBuff("[");
		PrintSib();
		if(disp<0x80000000)
		  LastPrintBuff("%s+%02lx]",(unsigned char *)regtable[arg],disp);
		else
		  LastPrintBuff("%s-%02lx]",(unsigned char *)regtable[arg],-disp);
		break;
	 case DISP8:
	 case DISP8B:
	 case DISP8W:
	 case DISP8D:
	 case DISP8Q:
	 case DISP8T:
		if(prefix)LastPrintBuff("%s:",(unsigned char *)regtable[prefix]);
		disp=disp&0xff;
		LastPrintBuff("[");
		PrintSib();
		if(disp<0x80)
		  LastPrintBuff("%s+%02lx]",(unsigned char *)regtable[arg],disp);
		else
		  LastPrintBuff("%s-%02lx]",(unsigned char *)regtable[arg],0x100-disp);
		break;
	 case MEMLOC:
	 case MEMLOCB:
	 case MEMLOCW:
	 case MEMLOCD:
	 case MEMLOCQ:
	 case MEMLOCT:
		if(prefix)LastPrintBuff("%s:",(unsigned char *)regtable[prefix]);
		LastPrintBuff("[");
		PrintSib();
		LastPrintBuff("%02lx]",arg);
		break;
	 case MEM:
	 case IMM:
		LastPrintBuff("%02lx",arg);
		break;
	 case IMMB:
		LastPrintBuff("byte %02lx",arg);
		break;
	 case IMMW:
		LastPrintBuff("word %02lx",arg);
		break;
	 case IMMD:
		LastPrintBuff("dword %02lx",arg);
		break;
	 case OFFSET:
		LastPrintBuff("offset %02lx",arg);
		break;
	 case STR:
		LastPrintBuff("\"%s\"",sarg);
		break;
	 case IMPORT:
		imports.printname(arg);
		break;
	 case EXPORT:
		exports.printname(arg);
      break;
  }
}

unsigned char disasm::modrmbyte(unsigned char *byte,unsigned char *type,unsigned long *value,
  unsigned long *displacement)
{ unsigned long offsib=0;
  unsigned char mod;
  unsigned char rm;
  if(addressprefix)return modrm16byte(byte,type,value,displacement);
  rm=byte[0]&7;
  mod=(byte[0]>>6)&3;
  *value=rm+1;
  switch(mod)
  { case 0:
		*type=INDIRECT;
		if(rm==5)
		{ *type=MEMLOC;
		  *value=((unsigned long *)(&byte[1]))[0];
		  return 4;
		}
		break;
	 case 1:
		*type=DISP8;
		break;
	 case 2:
		*type=DISP32;
		break;
	 case 3:
		*type=REG;
		if(operandprefix)(*value)+=8;
		return 0;
  }
  if(rm==4)
  { offsib=1;
	 lastsib=byte[1];
	 *value=(lastsib&7)+1;
	 lastsib=lastsib|1;
  }
  if((offsib)&&(*value==6))        //[*] case
  { if(mod==0)
	 { *type=MEMLOC;
		*value=((unsigned long *)(&byte[1+offsib]))[0];
		return 4+offsib;
	 }
  }
  if(*type==DISP32)
  { *displacement=((unsigned long *)(&byte[1+offsib]))[0];
	 return 4+offsib;
  }
  if(*type==DISP8)
  { *displacement=(unsigned long)byte[1+offsib];
	 return 1+offsib;
  }
  return 0+offsib;
}

unsigned char disasm::modrm16_8byte(unsigned char *byte,unsigned char *type,unsigned long *value,
  unsigned long *displacement)
{ unsigned char mod;
  unsigned char rm;
  rm=byte[0]&7;
  mod=(byte[0]>>6)&3;
  *value=rm+1;
  switch(mod)
  { case 0:
		*type=INDIRECT;
		if(rm==6)
		{ *type=MEMLOC;
		  *value=((unsigned long)(byte[2])<<8)+byte[1];
		  return 2;
		}
		break;
	 case 1:
		*type=DISP8;
		break;
	 case 2:
		*type=DISP32;
		break;
	 case 3:
		*type=REG;
		(*value)+=16;
		return 0;
  }
  *value=REG_BXSI+rm;
  switch(rm)
  { case 4:
		*value=REG_SI+8;
		break;
	 case 5:
		*value=REG_DI+8;
		break;
	 case 6:
		*value=REG_BP+8;
		break;
	 case 7:
		*value=REG_BX+8;
		break;
	 default:
		break;
  }
  if(*type==DISP8)
  { *displacement=(unsigned long)byte[1];
	 return 1;
  }
  if(*type==DISP32)
  { *displacement=((unsigned long)(byte[2])<<8)+byte[1];
	 return 2;
  }
  return 0;
}

unsigned char disasm::modrm16byte(unsigned char *byte,unsigned char *type,unsigned long *value,
  unsigned long *displacement)
{ unsigned char mod;
  unsigned char rm;
  rm=byte[0]&7;
  mod=(byte[0]>>6)&3;
  *value=rm+1;
  switch(mod)
  { case 0:
		*type=INDIRECT;
		if(rm==6)
		{ *type=MEMLOC;
		  *value=((unsigned long)(byte[2])<<8)+byte[1];
		  return 2;
		}
		break;
	 case 1:
		*type=DISP8;
		break;
	 case 2:
		*type=DISP32;
		break;
	 case 3:
		*type=REG;
		if(operandprefix)(*value)+=8;
		return 0;
  }
  *value=REG_BXSI+rm;
  switch(rm)
  { case 4:
		*value=REG_SI+8;
		break;
	 case 5:
		*value=REG_DI+8;
		break;
	 case 6:
		*value=REG_BP+8;
		break;
	 case 7:
		*value=REG_BX+8;
		break;
	 default:
		break;
  }
  if(*type==DISP8)
  { *displacement=(unsigned long)byte[1];
	 return 1;
  }
  if(*type==DISP32)
  { *displacement=((unsigned long)(byte[2])<<8)+byte[1];
	 return 2;
  }
  return 0;
}

unsigned char disasm::modrm8byte(unsigned char *byte,unsigned char *type,unsigned long *value,
  unsigned long *displacement)
{ unsigned long offsib=0;
  unsigned char mod;
  unsigned char rm;
  if(addressprefix)return modrm16_8byte(byte,type,value,displacement);
  rm=byte[0]&7;
  mod=(byte[0]>>6)&3;
  *value=rm+1;
  switch(mod)
  { case 0:
		*type=INDIRECT;
		if(rm==5)
		{ *type=MEMLOC;
		  *value=((unsigned long *)(&byte[1]))[0];
		  return 4;
		}
		break;
	 case 1:
		*type=DISP8;
		break;
	 case 2:
		*type=DISP32;
		break;
	 case 3:
		*type=REG;
      *value+=16;
		return 0;
  }
  if(rm==4)
  { offsib=1;
	 lastsib=byte[1];
	 *value=(lastsib&7)+1;
	 lastsib=lastsib|1;
  }
  if((offsib)&&(*value==6))        //[*] case
  { if(mod==0)
	 { *type=MEMLOC;
		*value=((unsigned long *)(&byte[1+offsib]))[0];
		return 4+offsib;
	 }
  }
  if(*type==DISP32)
  { *displacement=((unsigned long *)(&byte[1+offsib]))[0];
	 return 4+offsib;
  }
  if(*type==DISP8)
  { *displacement=(unsigned long)byte[1+offsib];
	 return 1+offsib;
  }
  return 0+offsib;
}

#pragma warn +sig

void disasm::PrintSib(void)
{ if(!lastsib)return;
  if(((lastsib>>3)&7)==4)return;
  LastPrintBuff("%s",(unsigned char *)regtable[((lastsib>>3)&7)+1]);
  switch(lastsib&0xc0)
  { case 0:
		LastPrintBuff("+");
		break;
	 case 0x40:
		LastPrintBuff("*2+");
		break;
	 case 0x80:
		LastPrintBuff("*4+");
		break;
	 case 0xc0:
		LastPrintBuff("*8+");
		break;
  }
}

struct asmlist *disasm::getdisassembly(void)
{ return disassembly;
}

unsigned long disasm::getinstct(void)
{ return instct;
}

