⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dis.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	      default :
	        error		 = SHELL_ERROR_OPTION;
		shell_error_data = argv[arg];
		ok		 = FALSE;
		break;		      
	    }
	    break;
	  case SHELL_TOKEN_NUMBER :
	    if( !address_valid )
	    {
		address_valid = TRUE;
		*address      = decode.number;
	    }
	    else if( !count_valid )
	    {
		count_valid = TRUE;
		*count	    = decode.number;
	    }
	    else
		ok = FALSE;
	    break;
	  default :
	    ok = FALSE;
	    break;
        }
    }

    if(!address_valid)
        ok = FALSE;

    return ok ?
        sys_validate_range( *address, (*count) * 4, sizeof(UINT32), FALSE ) :
        error;
}


/************************************************************************
 *                          do_dis
 ************************************************************************/
static void
do_dis( void )
{
    UINT32  i;
    UINT32  char_count;
    char    ch;
    char    line[80];	// must be long enough to hold disassembled inst line

    if (SHELL_PUTC( '\n' )) return;

    for (i=0; i<count; i++)
    {	
	disassemble(line, address, REG32(address));

	address += sizeof(UINT32);

	if (!more)
	    SHELL_DISABLE_MORE;

	if (SHELL_PUTS(line)) break;
    }

    SHELL_PUTC( '\n' );
}


/* Command definition for dis */
static t_cmd cmd_def =
{
    "dis",
    dis,
    "dis [-m] <address> [<count>]",

#if 0

/*   Does not work yet  -- '.' always invokes 'dump': */

    "Disassemble address range starting at 'address' (only MIPS32 instructions).\n"
    "'count' (default 16) specifies the number of data units to disassemble.\n"
    "More data may be disassembled by typing '.'",

#else

    "Disassemble code starting at <address> (only MIPS32 instructions).\n"
    "<count> (default 16) specifies the number of instructions to disassemble.",

#endif

    options,
    OPTION_COUNT,
    FALSE
};

#if 0
/* Command definition for '.' */
static t_cmd cmd_def_dot =
{
    ".",
    dis_dot,
    ".",
    "Continue dis following previous address.",
    NULL,
    0,
    TRUE
};
#endif

/************************************************************************
 *                          disassemble
 ************************************************************************/

static int 
disassemble(
	char	*dest,			/* destination line	*/
	UINT32	addr,			/* virtual address	*/
	UINT32	inst)			/* instruction		*/
{
	UINT32	op;			/* Opcode		*/
	UINT32	rs, rt, rd;		/* Reg src target dest	*/
	INT32	immed;			/* Signed immediate	*/
	UINT32	target;			/* Target for jumps	*/
	UINT32	shamt, funct;		/* ShiftAmount / funct	*/
	UINT32	sel;			/* Select field in COPz	*/
	char	const *opc;		/* Pointer to opcode	*/
	int	i;
	int	dix;			/* dest index		*/

	dix = 0;

	if ((UINT32)addr & 3) 
	{
		dix += sprintf(dest+dix, 
			"You can only disassemble from word boundaries.\n");
		return -1;
	};

	dix += sprintf(dest+dix, 
			"%08X:  %08X  ", addr, inst);

	/* Isolate all instruction fields */
	op     = (inst >> 26) & 0x3f;
	rs     = (inst >> 21) & 0x1f;
	rt     = (inst >> 16) & 0x1f;
	rd     = (inst >> 11) & 0x1f;
	immed  = (INT32) (
			(inst & 0x0000ffff)  | 
			((inst & 0x00008000) ? 0xffff0000 : 0));
	target = inst & 0x03ffffff;
	shamt  = (inst >>  6) & 0x1f;
	funct  = inst & 0x3f;
	sel    = inst & 0x7;

	if (op==0)  opc = special[funct]; else
	if (op==1)  opc = bcond[rt]; else
	if ((op==16) && (rs >= 16)) opc = cop0co[funct]; else
	if ((op==16) && (rs < 8))   opc = cop0[rs]; else
	if ((op==17) && (rs == 16)) opc = cop1s[funct]; else
	if ((op==17) && (rs == 17)) opc = cop1d[funct]; else
	if ((op==17) && (rs == 20)) opc = cop1w[funct]; else
	if ((op==17) && (rs < 16))  opc = cop1[rs]; else
	if (op==28) opc = spec2[funct]; else
		opc = opcode[op];

	if (!*opc)   opc = " resvd"; else
	if (inst==0) opc = " nop"; else

	if ((op==0) && (funct==33) && ((rs==0) || (rt==0))) 
	{
		opc = "jmove";
		if (rs==0) rs=rt;
	}

	dix += sprintf(dest+dix, "%s",opc+1);
	i = strlen(opc+1) ;
	while (i++<10) dix += sprintf(dest+dix, " ");

	addr += 4;

	switch (*opc) 
	{

	/* Formats for 'normal' instructions */
	  case 'o':
	    dix += sprintf(dest+dix, "%s,%d(%s)",
			   regs[rt], immed, regs[rs]);
	    break;

	  case 'i':
	    dix += sprintf(dest+dix, "%s,%s,%d",
			   regs[rt], regs[rs], immed);
	    break;

	  case 'I':
	    dix += sprintf(dest+dix, "%s,0x%X",
			   regs[rt], (immed<<16));
	    break;

	  case 't':
	    dix += sprintf(dest+dix, "0x%08X",
		  	  (target<<2) | (addr & 0xc0000000));
	    break;

	  case 'b':
	    dix += sprintf(dest+dix, "%s,%s,0x%08X",
			   regs[rs], regs[rt],( (INT32)addr+4*immed) );
	    break;

	  case 'c':
	    dix += sprintf(dest+dix, "0x%X", target);
	    break;

	/* Formats for special instructions */
	  case 's':
	    dix += sprintf(dest+dix, "%s,%s,%d", 
		 	   regs[rd], regs[rt], shamt);
	    break; 

	  case 'v':
	    dix += sprintf(dest+dix, "%s,%s,%s",
			   regs[rd], regs[rt], regs[rs]);
	    break;

	  case 'j':
	    dix += sprintf(dest+dix, "%s,%s",
			   regs[rd], regs[rs]);
	    break;

	  case 'B':
	    dix += sprintf(dest+dix, "%d", 
			   (UINT32) target>>6);
	    break;

	  case 'D':
	    dix += sprintf(dest+dix, "%s",
			   regs[rd]);
	    break;

	  case 'S':
	    dix += sprintf(dest+dix, "%s",
			   regs[rs]);
	    break;

	  case 'm':
	    dix += sprintf(dest+dix, "%s,%s",
			   regs[rs], regs[rt]);
	    break;

	  case 'r':
	    dix += sprintf(dest+dix, "%s,%s,%s",
			   regs[rd], regs[rs], regs[rt]);
	    break;

	/* Formats for branch conditionals */
	  case 'C':
	    dix += sprintf(dest+dix, "%s,0x%X",
			   regs[rs], (INT32)addr + 4*immed );
	    break;

	/* Formats for Coprocessor 0 */
	  case '0':
	    dix += sprintf(dest+dix, "%s,%s",
			   regs[rt], cp0regs[rd]);
	    if (sel)
	    	dix += sprintf(dest+dix, ",%d", sel);
	    break;

	/* Formats for Coprocessor 1 */
	  case '1':
	    dix += sprintf(dest+dix, "%s,%s",
			   regs[rt], fpregs[rd]);
	    if (sel)
	    	dix += sprintf(dest+dix, ",%d", sel);
	    break;

	  case '2':
	    dix += sprintf(dest+dix, "%s,%s",
			   fpregs[rt], fpregs[rd]);
	    if (sel)
	    	dix += sprintf(dest+dix, ",%d", sel);
	    break;

	  default:
	    // do nothing
	    break;
	}

#if 1
	dix += sprintf(dest+dix, "\n");
#else
	dix += sprintf(dest+dix, "%c", LF);
#endif
	return 0;
}

/************************************************************************
 *  Implementation : Public functions
 ************************************************************************/

/************************************************************************
 *
 *                          shell_dis_init
 *  Description :
 *  -------------
 *
 *  Initialise command
 *
 *  Return values :
 *  ---------------
 *
 *  void
 *
 ************************************************************************/
t_cmd *
shell_dis_init( void )
{
    return &cmd_def;
}

⌨️ 快捷键说明

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