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

📄 dsmlib.c

📁 vxworks5.5.1源代码。完整源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		reg(bits(12,15), ',');		reg(bits(16,19), ',');		reg(bits(0,3), ',');		reg(bits(8,11), 0);		break;		}	/* **** Drop through */	case 1:	case 2:	case 3:	    if (bit(4) && bit (7))		{		if (!bit(5) && !bit(6))		    {		    if (bits(22, 27) == 0)			{			opcode(instr, (bit(21) ? "MLA" : "MUL"),			       (bit(20) ? 'S' : 0));			reg(bits(16,19), ',');			reg(bits(0,3), ',');			reg(bits(8,11), 0);			if (bit(21))			    {			    outc(',');			    reg(bits(12,15), 0);			    }			break;			}		    if (bits(23,27) == 2 && bits (8, 11) == 0)			{			/* Swap */			opcode(instr, "SWP", (bit(22) ? 'B' : 0));			reg(bits(12,15), ',');			reg(bits(0,3), ',');			outc('[');			reg(bits(16,19), ']');			break;			}		    }		else		    {		    if (!bit(25) && (bit(20) || !bit(6)))			{			int l;						l = outs(bit(20) ? "LDR" : "STR");			l += cond(instr);			if (bit(6))			    {			    outc('S');			    outc(bit(5) ? 'H' : 'B');                	    l += 2;			    }			else			    {			    outc('H');			    l++;			    }			spacetocol9(l);			reg(bits(12,15), ',');			outc('[');			reg(bits(16,19), 0);			if (bit(24))			    outc(',');			else			    {			    outc(']');			    outc(',');			    }			if (bit(22))			    {			    outh(bits(0, 3) + (bits(8,11)<<4), bit(23));			    }			else			    {			    if (!bit(23)) outc('-');				reg(bits(0,3),0);			    }			    if (bit(24))				{				outc(']');				if (bit(21))				    outc('!');				}			break;			}		    }		}	    if (bits(4, 27) == 0x12fff1)		{		opcode(instr, "BX", 0);		reg(bits(0, 3), 0);		break;		}	    if (instr == 0xe1a00000L)		{		opcode(instr, "NOP", 0);		break;		}		{ /* data processing */		int op = (int)bits(21,24);		const char *opnames = "AND\0EOR\0SUB\0RSB\0ADD\0ADC\0SBC\0RSC\0"				      "TST\0TEQ\0CMP\0CMN\0ORR\0MOV\0BIC\0MVN";		if (op >= 8 && op < 12 && !bit(20))		    {		    if ((op & 1) == 0)			{			opcode(instr, "MRS", 0);			reg(bits(12,15), ',');			if (op == 8)			    outs("cpsr");			else			    outs("spsr");			oddity = (bits(0, 11) != 0 || bits(16, 19) != 15);			break;			}		    else			{			    char *rname = op == 9 ? "cpsr" : "spsr";			    int rn = (int)bits(16, 19);			    char *part = rn == 1 ? "ctl" :			                 rn == 8 ? "flg" :			                 rn == 9 ? "all" :			                           "?";			    opcode(instr, "MSR", 0);			    outs(rname);			    outf("_%s,", part);			    oddity = bits(12,15) != 15;			}		    }		else		    {		    int ch = (!bit(20)) ? 0 :				(op>=8 && op<12) ? (bits(12,15)==15 ? 'P' : 0) :				'S';		    opcode(instr, opnames+4*op, ch);		    if (!(op >= 8 && op < 12))			{ /* not TST TEQ CMP CMN */			  /* print the dest reg */			reg(bits(12,15), ',');			}		    if (op != 13 && op != 15)			{ /* not MOV MVN */			reg(bits(16,19), ',');			}		    }		if (bit(25))		    { /* rhs is immediate */		    int shift = 2 * (int)bits(8,11);		    INT32 operand = ror(bits(0,7), shift);		    outh(operand, 1);		    }		else		    { /* rhs is a register */		    shiftedreg(instr);		    }		}	    break;	case 0xA:	case 0xB:	    opcode(instr, (bit(24) ? "BL" : "B"), 0);		{		INT32 offset =			  (((INT32)bits(0,23))<<8)>>6; /* sign extend and * 4 */		address += offset + 8;		prtAddress(address);		}	    break;	case 6:	case 7:	/*	 * Cope with the case where register shift register is specified	 * as this is an undefined instruction rather than an LDR or STR	 */	    if (bit(4))		{		outs("Undefined Instruction");		break;		}       /* ***** Drop through to always LDR / STR case */	case 4:	case 5:	    {	    int l;	    l = outs(bit(20) ? "LDR" : "STR");	    l += cond(instr);	    if (bit(22))		{		outc('B');		l++;		}	    if (!bit(24) && bit(21))  /* post, writeback */		{		outc('T');		l++;		}	    spacetocol9(l);	    reg(bits(12,15), ',');	    outAddress(instr, address, bits(0,11), prtAddress);	    break;	    }	case 8:	case 9:	{	int l;	l = outs(bit(20) ? "LDM" : "STM");	l += cond(instr);	l += outs("DA\0\0IA\0\0DB\0\0IB" + 4*(int)bits(23,24));	spacetocol9(l);	reg(bits(16,19), 0);	if (bit(21))	    outc('!');	outc(',');	outregset(instr);	if (bit(22)) outc('^');	    break;	}	case 0xF:	    opcode(instr, "SWI", 0);		{		INT32 swino = bits(0,23);		outx(swino);		}	    break;	case 0xE:	   if (bit(4)==0)		{ /* CP data processing */		switch(bits(8,11))		    {		    case 1:			fp_cpdo(instr, &oddity);			break;		    default:			generic_cpdo(instr);			break;		    }		}	    else		{ /* CP reg to/from ARM reg */		switch (bits(8,11))		    {		    case 1:			fp_cprt(instr);			break;		    default:			generic_cprt(instr);			break;		    }	   }	   break;	case 0xC:	case 0xD:	    switch (bits(8,11))		{		case 1:		    fp_cpdt(instr, address, prtAddress);		    break;		case 2:		    fm_cpdt(instr, address, prtAddress);		    break;		default:		    generic_cpdt(instr, address, prtAddress);		    break;		}	    break;	default:	    outs("EQUD    ");	    outx(instr);	    errnoSet (S_dsmLib_UNKNOWN_INSTRUCTION);	    break;    } /* endswitch */    if (oddity)	outs(" ; (?)");    outc('\n');    return 4;    } /* disass_32() */#endif /* INCLUDE_ARM_DISASM */#ifdef INCLUDE_THUMB_DISASM/********************************************************************************* t_opcode - display the opcode of a Thumb instruction** RETURNS: N/A** NOMANUAL**/LOCAL void t_opcode    (    const char *	op	/* the opcode as a string */    )    {    int l;    /* display the opcode */    l = outs(op);    /* pad with spaces to column 9 */    spacetocol9(l);    return;    } /* t_opcode() *//********************************************************************************* disass_16 - disassemble a Thumb (16-bit) instruction** RETURNS: size of instruction, in bytes** NOMANUAL**/UINT32 disass_16    (    UINT32	instr,		/* the value of the instruction */    UINT32	instr2,		/* the value of the next instruction */    UINT32	address,	/* the address to print before instruction */    VOIDFUNCPTR	prtAddress	/* routine to print addresses as symbols */    )    {    INT32 Rd, Rm, Rn, Ro;    INT32 imm5, imm8, imm11;    INT32 L, B;    Rd = bits(0, 2);    Rm = bits(3, 5);    Rn = bits(6, 8);    Ro = bits(8, 10);#define imm3 Rn    imm11 = bits(0, 10);    imm8 = bits(0, 7);    imm5 = bits(6, 10);    L = bit(11);#define SP L#define H L    B = bit(10);#define S B#define I B    switch (bits(11, 15))	{	case 3:	    if (bit(9) == 0 && I && imm3 == 0)		{		t_opcode("MOV");		reg(Rd, ',');		reg(Rm, 0);		break;		}	    t_opcode(bit(9) ? "SUB" : "ADD");	    reg(Rd, ',');	    if (Rd != Rm)		reg(Rm, ',');	    I ? outh(imm3, 1) : reg(Rn, 0 );	    break;	case 10:	case 11:	    t_opcode("STR\0*STRH\0STRB\0LDSB\0LDR\0*LDRH\0LDRB\0LDSH" +		bits(9, 11) * 5);	    reg(Rd, ',');	    outc('[');	    reg(Rm, ',');	    reg(Rn, ']');	    break;	case 12:	case 13:	    imm5 <<= 1;	case 16:	case 17:	    imm5 <<= 1;	case 14:	case 15:	    t_opcode("STR\0*LDR\0*STRB\0LDRB\0STRH\0LDRH\0" +		(bits(11, 15) - 12) * 5);	    reg(Rd, ',');	    outc('[');	    reg(Rm, ',');	    outh(imm5, 1);	    outc(']');	    break;	case 0:	case 1:	case 2:	    t_opcode("LSL\0LSR\0ASR" + bits(11, 12) * 4);	    reg(Rd, ',');	    if (Rd != Rm)		reg(Rm, ',');	    outh(imm5, 1);	    break;	case 8:	    {	    INT32 op;	    op = bits(6, 10);	    if (op < 16)		{		t_opcode("AND\0EOR\0LSL\0LSR\0ASR\0ADC\0SBC\0ROR\0"			 "TST\0NEG\0CMP\0CMN\0ORR\0MUL\0BIC\0MVN" + op * 4);		}	    else		{		if (op & 2)		    Rd += 8;		if (op & 1)		    Rm += 8;		switch(op)		    {		    case 17:		    case 18:		    case 19:			t_opcode("ADD");			break;		    case 21:		    case 22:		    case 23:			t_opcode("CMP");			break;		    case 25:		    case 26:		    case 27:			t_opcode("MOV");			break;		    case 16:		    case 20:		    case 24:		    case 30:		    case 31:			t_opcode("Undefined");			outc('\n');			return 2;		    case 28:		    case 29:			t_opcode("BX");			reg(Rm, 0);			outc('\n');			return 2;		    } /* end switch(op) */		} /* endelse (op >= 16) */	    reg(Rd, ',');	    reg(Rm, 0);	    break;	    } /* endcase 8 */	case 4:	case 5:	case 6:	case 7:	    /* ADD/SUB/MOV/CMP (large) immediate */	    t_opcode("MOV\0CMP\0ADD\0SUB" + bits(11, 12) * 4);	    reg(Ro, ',');	    outh(imm8, 1);	    break;	case 18:	case 19:	    /*	     * LDR/STR SP-relative. ARM disassembler code would try to look	     * this up, but there seems little point in this. Display as	     * LDR Ro, [SP, #imm]	     */	    t_opcode("STR\0LDR" + L * 4);	    reg(Ro, ',');	    imm8 <<= 2;	    outc('[');	    reg(13, ',');	    outh(imm8, 1);	    outc(']');	    break;	case 28:	    /* unconditional branch */	    t_opcode("B");	    imm11 = (imm11 << 21) / (1 << 20);	    prtAddress(address + imm11 + 4);	    break;	case 22:	case 23:	    if (!bit(10))		{		if (bits(8, 11) != 0)		    {		    t_opcode("Undefined");		    }		else		    {		    imm8 = (imm8 & 0x7f) << 2;		    t_opcode(bit(7) ? "SUB" : "ADD");		    reg(13, ',');		    outh(imm8, 1);		    }		}	    else		{		if (bit(9))		    {		    t_opcode("Undefined");		    }		else		    {		    instr &= 0x1ff;		    if (instr & 0x100)			{			instr &= ~0x100;			if (L)			    instr |= 0x8000;			else			    instr |= 0x4000;			}		    t_opcode("PUSH\0POP" + L * 5);		    outregset(instr);		    }		}	    break;	case 9:	    t_opcode("LDR");	    reg(Ro, ',');	    imm8 <<= 2;	    address = (address + 4) & ~3;	    prtAddress(address + imm8);	    break;	case 24:	case 25:	    instr &= 0xFF;	    t_opcode("STMIA\0LDMIA" + L * 6);	    reg(Ro, '!');	    outc(',');	    outregset(instr);	    break;	case 20:	case 21:	    t_opcode("ADR\0ADD" + SP * 4);	    reg(Ro, ',');	    imm8 <<= 2;	    if (!SP)		{		address = (address + 4) & ~3;		prtAddress(address + imm8);		}	    else		{		reg(13, ',');		outh(imm8, 1);		}	    break;	case 26:	case 27:	    { /* Either SWI or conditional branch */	    INT32 op;	    op = bits(8, 11);	    if (op == 15)		{ /* SWI */		t_opcode("SWI");		outx(imm8);		}	    else		{		/* conditional branch: make up ARM instruction to display B?? */		opcode(op << 28, "B", 0);		imm8 = (imm8 << 24) / (1 << 23);		prtAddress(address + imm8 + 4);		}	    break;	    }	case 30:	    { /*	       * BL prefix: the BL Thumb instruction is actually TWO 16-bit	       * instructions, the BL prefix and the BL itself.	       */	    INT32 offset;	    if ((instr2 & 0xf800) == 0xf800)		{ /* if next instruction is the BL itself */		t_opcode("BL");		offset = instr2 & 0x7ff;		offset = (((imm11 << 11) | offset) << 10) / (1 << 9);		prtAddress(address + offset + 4);		outc('\n');		return 4; /* Note two 16-bit instructions */		}	    else		{ /* BL prefix, not followed by BL: not defined */		t_opcode("first half of BL instruction");		}	    break;	    }	case 31:	    /*	     * BL suffix, but we should already have dealt with it, if	     * preceded by a BL prefix.	     */	    t_opcode("second half of BL instruction");	    break;	default:	    t_opcode("Undefined");	    break;	} /* endswitch */    outc('\n');    return 2;    } /* disass_16() */#undef imm3#undef SP#undef S#undef H#undef H1#undef H2#endif/********************************************************************************* nPrtAddress - print addresses as numbers** RETURNS: N/A** NOMANUAL**/LOCAL void nPrtAddress    (    int	address    )    {    printf ("0x%x", address);    }/********************************************************************************* dsmInst - disassemble and print a single instruction** This routine disassembles and prints a single instruction on standard* output.  The function passed as parameter <prtAddress> is used to print any* operands that might be construed as addresses.  The function could be a* subroutine that prints a number or looks up the address in a symbol table.* The disassembled instruction will be prepended with the address passed as* a parameter.** ADDRESS-PRINTING ROUTINE* Many assembly language operands are addresses.  In order to print these* addresses symbolically, dsmInst() calls a user-supplied routine, passed as a* parameter, to do the actual printing.  The routine should be declared as:* .CS*    void prtAddress (address)*        int address;	/@ address to print @/* .CE** When called, the routine prints the address on standard output in either* numeric or symbolic form.  For example, the address-printing routine used* by l() looks up the address in the system symbol table and prints the* symbol associated with it, if there is one.  If not, the routine prints the* address as a hex number.** If the <prtAddress> argument to dsmInst() is NULL, a default print routine is* used, which prints the address as a hexadecimal number.** The directive EQUD (declare word) is printed for unrecognized instructions.** RETURNS : The size of the instruction in units of sizeof(INSTR).*/int dsmInst    (    FAST INSTR *	binInst,	/* Pointer to the instruction */    int			address,	/* Address prepended to instruction */    VOIDFUNCPTR		prtAddress	/* Address printing function */    )    {#ifdef INCLUDE_THUMB_DISASM    UINT16 instr2 = 0;#endif    /* If no address printing function has been supplied, use default */    if (prtAddress == NULL)	prtAddress = nPrtAddress;    /* Print the address first, then the instruction in hex */#ifdef INCLUDE_ARM_DISASM    printf("%08x  %08x  ", address, (UINT32)*binInst);    return disass_32((UINT32)*binInst, (UINT32)address, prtAddress) /                                                                 sizeof(INSTR);#endif#ifdef INCLUDE_THUMB_DISASM    if (INSTR_IS((*(UINT16 *)binInst), T_BL0))	{	instr2 = *(((UINT16 *)binInst) + 1);	if (INSTR_IS(instr2, T_BL1))	    {	    /*	     * Instruction is a BL: i.e. this instruction is a BL	     * prefix and the next instruction is the BL itself. So, this	     * instruction is effectively 32-bits long. Get the next 16-bit	     * half of the instruction and display all of it as a 32-bit int.	    */	    printf("%08x  %04x%04x  ", address, instr2, *(UINT16 *)binInst);	    }	else	    /* BL prefix not followed by BL suffix */	    printf("%08x  %04x      ", address,  *(UINT16 *)binInst);	}    else	/* Normal (16-bit) Thumb instruction */	printf("%08x  %04x      ", address,  *(UINT16 *)binInst);    return disass_16((UINT32)(*(UINT16 *)binInst), (UINT32)instr2,    			(UINT32)address, prtAddress) / sizeof(INSTR);#endif    } /* dsmInst() *//********************************************************************************* dsmNbytes - determine the size of an instruction** This routine reports the size, in bytes, of an instruction.** RETURNS:* The size of the instruction, or* 0 if the instruction is unrecognized.**/int dsmNbytes    (    FAST INSTR *	binInst	/* Pointer to the instruction */    )    {#if (ARM_THUMB)    return INSTR_IS (*binInst, T_BL0) ? 2 * sizeof(INSTR) : sizeof(INSTR);#else    return sizeof (INSTR);#endif    } /* dsmNbytes() */

⌨️ 快捷键说明

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