uasm.c

来自「MMURTL(tm) Computer Operating System Ver」· C语言 代码 · 共 716 行 · 第 1/2 页

C
716
字号
    buf[i] = getbyte();

  /* sign extend the value into a U32 */

  for (; i<extend; i++)
    buf[i] = (buf[i-1] & 0x80) ? 0xff : 0;

  if (s)		/* outputs the segment value of FAR pointer */
  {
	xprintf("%02x%02x",buf[n-1],buf[n-2]);
    n -= 2;
  }

  if (extend > n)
  {
    if (!optional)
	xprintf("+");
	n = 4;
  }
  switch (n)
  {
    case 1: {
			xprintf("%02x",buf[0]);
    		break;
    		}
    case 2:	{
			xprintf("%02x%02x",buf[1],buf[0]);
    		break;
    		}
    case 4:	{
			xprintf("%02x%02x%02x%02x",buf[3],buf[2],buf[1],buf[0]);
    		break;
    		}
  }
}

/*------------------------------------------------------------------------*/

void reg_name(U8 which, char size)
{
  if (size == 'F')
  {
    xprintf( "st(%d)",which);

    return;
  }
  if (((size == 'v') && (opsize == 32)) || (size == 'd'))
  {
    xprintf("E");
  }
  if (size == 'b')
  {
    xprintf( "%s", breg_names[which]);
  }
  else
  {
    xprintf( "%s", wreg_names[which]);
  }
}

/******************************************************************
   This takes in two chars that represent part of the op code and
   puts out the proper text to match what the letter represents.
   c is the first char after the tilde and t is next one. See
   opcode1[] strings for what the chars mean.
*******************************************************************/

void escape(char c, char t)
{
  S32  delta, vals;
  U8 b2;
  S8 valsb;
  S16 valsw;

  switch (c)
  {
    case 'A':                             /* Direct Address */
	    ohex(t, 4, 0, 32);
	    break;
    case 'C':                             /* Reg of R/M picks control reg */
		xprintf("CR%d",reg(modrm()));
	    break;
    case 'D':                             /* Reg of R/M pick debug reg */
		xprintf("DR%d",modrm());
		break;
    case 'E':                             /* R/M picks operand */
		do_modrm(t);
		break;
    case 'G':                             /* Reg of R/M picks general reg */
		if (t == 'F')
        	reg_name((modrm()&7), t);
		else
		reg_name(reg(modrm()), t);
		break;
    case 'I':                             /* Immediate data */
		ohex(t, 0, 0, opsize);
		break;
    case 'J':                             /* Relative IP offset */
		switch (bytes(t))
		{
        case 1:
          valsb = getbyte();		/* must remian signed! */
          vals = valsb;
          break;
        case 2:
          valsb = getbyte();        /*RAB  Made SIGNEd bytes/Words */
          valsw = getbyte()<<8;
          vals = valsw + valsb;
          break;
        case 4:
          vals = getbyte();
          vals |= getbyte() << 8;
          vals |= getbyte() << 16;
          vals |= getbyte() << 24;
          break;
		}
		delta = addrIn + vals;
	    xprintf( "%x",delta);
		break;
    case 'M':                             /* R/M picks memory */
		do_modrm(t);
		break;
	case 'O':                             /* NO R/M, Offset only */
		decode("~p:[");
		ohex(t, 4, 0, 32);
		xprintf("]");
		break;
    case 'R':                             /* Mod of R/M pick REG only */
		do_modrm(t);
		break;
    case 'S':                             /* Reg of R/M picks seg reg */
	    xprintf( "%s", seg_names[reg(modrm())]);
		break;
    case 'T':                             /* Reg of R/M picks test reg */
		xprintf( "TR%d",modrm());
		break;
    case 'X':                             /* DS:ESI */
		xprintf("DS:[ESI]");
		break;
	case 'Y':                             /* ES:EDI */
		xprintf("ES:[EDI]");
		break;
    case '2':                             /* Prefix of 2 byte opcode */
		b2 = getbyte();
		if (b2 < 0x10)
			decode(SecOp00[b2]);
		else if ((b2 > 0x1F) && (b2 < 0x30))
			decode(SecOp20[b2-0x20]);
		else if ((b2 > 0x7F) && (b2 < 0xC0))
			decode(SecOp80[b2-0x80]);
		else
		    xprintf("<bogus>");
		break;
	case 'e':                 /*  t is part of reg name */
		if (opsize == 32)
		{
			if (t == 'w')     /* put out "d" if t is "w" on 32 bit opsize */
		  		xprintf("D");
			else
			{
			  xprintf("E");  /* put out "E" if not t <> "w" then put t */
			  xprintf("%c",t);
			}
		}
		else {
			  xprintf("%c",t);
		}
		break;
    case 'f':                /* floating point */
	    xprintf("<Float Op>");

/*		floating_point(t-'0');  */

		break;
    case 'g':                             /* do R/M group 'n' */
		decode(groups[t-'0'][reg(modrm())]);
		break;
    case 'p':                             /* Segment prefix */
		switch (t)
		{
		case 'C':                         /* CS */
		case 'D':                         /* DS */
		case 'E':                         /* ES */
		case 'F':                         /* FS */
		case 'G':                         /* GS */
		case 'S':                         /* SS */
		  prefix = t;
          decode(opmap1[getbyte()]);
          break;
 		case ':':
          if (prefix) {
          	xprintf("%cS:",prefix);
          }
          break;
    	case ' ':
          decode(opmap1[getbyte()]);
          break;
		}
		break;
    case 's':								/* Size override */
		if (t=='o') {						/* o is operand */
		  opsize = 48 - opsize;
		  decode(opmap1[getbyte()]);
  	    }
	    break;
  }
}


/******************************************
This expands and outputs the instruction
string passed in if it finds the escape
character (tilde).
******************************************/

void decode(char *s)
{
  char c;

  if (s == 0)                   /* if NULL pointer, then it's BAD */
  {
    xprintf("<invalid>");
  }
  while ((c = *s++) != 0)       /* put next char in c */
  {
    if (c == '~')               /* if c is ~ then ESCAPE */
    {
      c = *s++;                 /* get letter representing value */
      escape(c, *s++);
    }
    else
      if (c == ' ') 	         /* space */
		xprintf(" ");
	  else {
		xprintf("%c",c);         /* else put out the char found! */
		}
  }
}


/* outputs 'scale-index-base' instructions */

void do_sib(int m)
{
  int s, i, b;
  s = ((sib()) >> 6) & 7;		/* SSxxxxxx Scale */
  i = ((sib()) >> 3) & 7;		/* xxIIIxxx Index */
  b = sib() & 7;				/* xxxxxBBB Base  */
  switch (b)
  {
    case 0: decode("~p:[EAX"); break;
    case 1: decode("~p:[ECX"); break;
    case 2: decode("~p:[EDX"); break;
    case 3: decode("~p:[EBX"); break;
    case 4: decode("~p:[ESP"); break;
    case 5:
      if (m == 0)
      {
        decode("~p:[");
        ohex('d', 4, 0, 32);
      }
      else
        decode("~p:[EBP");
      break;
    case 6: decode("~p:[ESI"); break;
    case 7: decode("~p:[EDI"); break;
  }
  switch (i)
  {
    case 0: xprintf("+EAX"); break;
    case 1: xprintf("+ECX"); break;
    case 2: xprintf("+EDX"); break;
    case 3: xprintf("+EBX"); break;
    case 4: break;
    case 5: xprintf("+EBP"); break;
    case 6: xprintf("+ESI"); break;
    case 7: xprintf("+EDI"); break;
  }
  if (i != 4)
    switch (s)
    {
      case 0: break;
      case 1: xprintf("*2"); break;
      case 2: xprintf("*4"); break;
      case 3: xprintf("*8"); break;

    }
}
/*------------------------------------------------------------------------*/
void do_modrm(char t)
{
  int m;
  int r;

  m = ((modrm()) >> 6) & 7;
  r = modrm() & 7;

  if (m == 3)
  {
    reg_name(r, t);
    return;
  }
  if ((m == 0) && (r == 5))
  {
    decode("~p:[");
    ohex('d', 4, 0, 32);
    xprintf("]");
    return;
  }

  if (r != 4)
    decode("~p:[");

  switch (r)
    {
      case 0: xprintf("EAX"); break;
      case 1: xprintf("ECX"); break;
      case 2: xprintf("EDX"); break;
      case 3: xprintf("EBX"); break;
      case 4: do_sib(m); break;
      case 5: xprintf("EBP"); break;
      case 6: xprintf("ESI"); break;
      case 7: xprintf("EDI"); break;
  }
  switch (m)
  {
    case 1:
      ohex('b', 4, 0, 32);
      break;
    case 2:
      xprintf("+");
      ohex('v', 4, 0, 32);
      break;
  }
  xprintf("]");
}

/***********************************************
  This disassembles one instruction each time it
  is called.
************************************************/

U32 disassemble(U32 Addr)
{
  prefix = 0;
  fmodrmv = 0;
  fsibv = 0;
  opsize = SEGSIZE;	 /* default operand size is DWORD */
  addrIn = Addr;

  xprintf( "%08x   ", addrIn);

  decode(opmap1[getbyte()]);	/* decode instruction and output */

  xprintf( "\r\n");
  return addrIn;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?