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

📄 dsmlib.c

📁 vxworks5.5.1源代码。完整源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* dsmLib.c - ARM disassembler *//* * Copyright 1991-1998 Advanced RISC Machines Ltd. and Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01e,04sep98,cdp  make Thumb support dependent on ARM_THUMB.01d,27oct97,kkk  took out "***EOF***" line from end of file.01c,10oct97,jpd  tidied.01b,19jun97,jpd  added Thumb (ARM7TDMI_T) support.01a,15aug96,jpd  written, based on 680X0 version 03o and also ARM Ltd.'s		 disassembler sources*//*This library contains everything necessary to print ARM and Thumbobject code in assembly language format.  The disassembly is done innative ARM/Thumb format.The programming interface is via dsmInst(), which prints a single disassembledinstruction, and dsmNbytes(), which reports the size of an instruction.To disassemble from the shell, use l(), which calls thislibrary to do the actual work.  See dbgLib() for details.INTERNALThis code is very largely based on the ARM Ltd. disassembler code, and sodoes not conform to the recommended structure for VxWorks disassemblers.INCLUDE FILE: dsmLib.hSEE ALSO: dbgLib.I "ARM Architecture Reference Manual,".I "ARM 7TDMI Data Sheet,".I "ARM 710A Data Sheet,".I "ARM 810 Data Sheet,".I "Digital Semiconductor SA-110 Microprocessor Technical Reference Manual."*/#include "vxWorks.h"#include "dsmLib.h"#include "string.h"#include "stdio.h"#include "errnoLib.h"/* * check that this compiler does sign extension when an int is shifted right * because code below relies on its doing so. */#if (((INT32)-1L) >> 1) > 0#	error right shifting an int does not perform sign extension#endif#if (ARM_THUMB)#define INCLUDE_THUMB_DISASM#undef  INCLUDE_ARM_DISASM#else#undef  INCLUDE_THUMB_DISASM#define INCLUDE_ARM_DISASM#endif/* ---------------- Output Functions --------------------- */#define outc(h)   (printf("%c",h))#define outf(f,s) (printf(f,s))#define outi(n)   outf("#%ld",(unsigned long)n)#define outx(n)   (printf("0x%lx",(unsigned long)n))#define outs(s)   (printf("%s", s), (strlen(s)))/* ---------------- Bit twiddlers ------------------------ *//* * The casts to UINT32 in bit() and bits() are redundant, but required by * some buggy compilers. */#define bp(n) (((UINT32)1L<<(n)))#define bit(n) (((UINT32)(instr & bp(n)))>>(n))#define bits(m,n) (((UINT32)(instr & (bp(n)-bp(m)+bp(n))))>>(m))#define ror(n,b) (((n)>>(b))|((n)<<(32-(b)))) /* n right rotated b bits *//********************************************************************************* reg - display register name** RETURNS: N/A** NOMANUAL**/LOCAL void reg    (    UINT32	rno,	/* register number */    int		ch	/* char to display after reg, 0 => do nothing */    )    {    /* Replace "r15" with "pc" */    if (rno == 15)	outs("pc");    else	outf("r%d", rno);    if (ch != 0)	outc(ch);    return;    } /* reg() *//********************************************************************************* outh - display immediate value in hex** RETURNS: N/A** NOMANUAL**/LOCAL void outh    (    UINT32	n,	/* number to display */    UINT32	pos	/* whether number is positive */    )    {    /* ARM assembler immediate values are preceded by '#' */    outc('#');    if (!pos)	outc('-');    /* decimal values by default, precede hex values with '0x' */    if (n < 10)	outf("%d", n);    else	outx(n);    return;    } /* outh() *//********************************************************************************* spacetocol9 - tab to column 9** RETURNS: N/A** NOMANUAL**/LOCAL void spacetocol9    (    int	l	/* current column position */    )    {    for (; l < 9 ; l++)	outc(' ');    return;    } /* spacetocol9() *//********************************************************************************* outregset - display register set of load/store multiple instruction** RETURNS: N/A** NOMANUAL**/LOCAL void outregset    (    UINT32	instr	/* the value of the instruction */    )    {    BOOL started = FALSE, string = FALSE;    UINT32 i, first = 0, last = 0;    /* display the start of list char */    outc('{');    /* check for presence of each register in list */    for (i = 0; i < 16; i++)	{	if (bit(i))	    {	    /* register is in list */	    if (!started)		{		/* not currently doing a consecutive list of reg numbers */		reg(i, 0);	/* print starting register */		started = TRUE;		first = last = i;		}	    else		/* currently in a list */		if (i == last+1)		    {		    string = TRUE;		    last = i;		    }		else		    /* not consecutive */		    {		    if (i > last+1 && string)			{			outc((first == last-1) ? ',' : '-');			reg(last, 0);			string = FALSE;			}		    outc(',');		    reg(i, 0);		    first = last = i;		    }	    }	} /* endfor */    if (string)	{	outc((first == last-1) ? ',' : '-');	reg(last, 0);	}    outc('}');    return;    } /* outregset() *//********************************************************************************* cond - display condition code of instruction** RETURNS: number of characters written.** NOMANUAL**/LOCAL int cond    (    UINT32	instr    )    {    const char *ccnames = "EQ\0\0NE\0\0CS\0\0CC\0\0MI\0\0PL\0\0VS\0\0VC\0\0"			  "HI\0\0LS\0\0GE\0\0LT\0\0GT\0\0LE\0\0\0\0\0\0NV";    return outs(ccnames+4*(int)bits(28,31));    } /* cond() *//********************************************************************************* opcode - display the opcode of an ARM instruction** This routine is also used in the display of a conditional branch ARM* instruction.** RETURNS: N/A** NOMANUAL**/LOCAL void opcode    (    UINT32	instr,	/* the value of the instruction */    const char *op,	/* the opcode as a string */    char	ch	/* any additional suffix char 0 => display nothing */    )    {    int l;    /* display the opcode */    l = outs(op);    /* display any condition code */    l += cond(instr);    /* display any suffix character */    if (ch != 0)	{	outc(ch);	l++;	}    /* pad with spaces to column 9 */    spacetocol9(l);    return;    } /* opcode() */#ifdef INCLUDE_ARM_DISASM/********************************************************************************* freg - display FP register name** RETURNS: N/A** NOMANUAL**/LOCAL void freg    (    UINT32	rno,	/* register number */    int		ch	/* char to display after reg, 0 => do nothing */    )    {    outf("f%d", rno);    if (ch != 0)	outc(ch);    return;    } /* freg() *//********************************************************************************* shiftedreg - display shifted register operand** RETURNS: N/A** NOMANUAL**/LOCAL void shiftedreg    (    UINT32	instr    )    {    char *shiftname = "LSL\0LSR\0ASR\0ROR" + 4*(int)bits(5,6);    /* display register name */    reg(bits(0,3), 0); /* offset is a (shifted) reg */    if (bit(4))	{	/* register shift */	outf(",%s ", shiftname);	reg(bits(8,11), 0);	}    else	if (bits(5,11) != 0)	    {	    /* immediate shift */	    if (bits(5,11) == 3)		outs(",RRX");	    else		{		outf(",%s ", shiftname);		if (bits(5,11) == 1 || bits(5,11) == 2)		    outi(32L);		else		    outi(bits(7,11));		}	    }    return;    } /* shiftedreg() *//********************************************************************************* outAddress - display an address as part of an instruction** RETURNS: N/A** NOMANUAL**/LOCAL void outAddress    (    UINT32	instr,		/* value of instruction */    UINT32	address,	/* address */    INT32	offset,		/* any offset part of instruction */    VOIDFUNCPTR	prtAddress	/* routine to print addresses as symbols */    )    {    if (bits(16,19) == 15 && bit(24) && !bit(25))	{	/* pc based, pre, imm */	if (!bit(23))	    offset = -offset;	address = address + offset + 8;	prtAddress(address);	}    else	{	outc('[');	reg(bits(16,19), (bit(24) ? 0 : ']'));	outc(',');	if (!bit(25))	    {	    /* offset is an immediate */	    outh(offset, bit(23));	    }	else	    {	    if (!bit(23))		outc('-');	    shiftedreg(instr);	    }	if (bit(24))	    {	    outc(']');	    if (bit(21))		outc('!');	    }	}    return;    } /* outAddress() *//********************************************************************************* generic_cpdo - display generic coprocessor data processing instruction** RETURNS: N/A** NOMANUAL**/LOCAL void generic_cpdo    (    UINT32	instr    )    {    opcode(instr, "CDP", 0);    outf("p%d,", bits(8,11));    outx(bits(20,23));    outc(',');    outf("c%d,", bits(12,15));	/* CRd */    outf("c%d,", bits(16,19));	/* CRn */    outf("c%d,", bits(0,3));	/* CRm */    outh(bits(5,7),1);    return;    } /* generic_cpdo() *//********************************************************************************* generic_cprt - display generic coprocessor register transfer instruction** RETURNS: N/A** NOMANUAL**/LOCAL void generic_cprt    (    UINT32	instr    )    {    opcode(instr, (bit(20) ? "MRC" : "MCR"), 0);    outf("p%d,", bits(8,11));    outx(bits(21,23));    outc(',');    reg(bits(12,15), ',');    outf("c%d,",bits(16,19));	/* CRn */    outf("c%d,",bits(0,3));	/* CRm */    outh(bits(5,7),1);    return;    } /* generic_cprt() *//********************************************************************************* generic_cpdt - display a generic coprocessor data transfer instruction** RETURNS: N/A** NOMANUAL**/LOCAL void generic_cpdt    (    UINT32	instr,    UINT32	address,    VOIDFUNCPTR	prtAddress    )    {    opcode(instr, (bit(20) ? "LDC" : "STC"), (bit(22) ? 'L' : 0));    outf("p%d,",bits(8,11));    outf("c%d,",bits(12,15));    outAddress(instr, address, 4*bits(0,7), prtAddress);    return;    } /* generic_cpdt() *//********************************************************************************* fp_dt_widthname - display floating-point data transfer width name** RETURNS: the character representing the width specifier** NOMANUAL**/LOCAL char fp_dt_widthname    (    UINT32	instr    )    {    return "SDEP"[bit(15) + 2*bit(22)];    } /* fp_dt_widthname() *//********************************************************************************* fp_widthname - display floating-point width name** RETURNS: the character representing the width name** NOMANUAL**/LOCAL char fp_widthname    (    UINT32	instr    )    {    return "SDEP"[bit(7) + 2*bit(19)];    } /* fp_widthname() *//********************************************************************************* fp_rounding - display floating-point rounding** RETURNS: the character representing the rounding** NOMANUAL**/LOCAL char *fp_rounding    (    UINT32	instr    )    {    return "\0\0P\0M\0Z" + 2*bits(5,6);    } /* fp_rounding() *//********************************************************************************* fp_mfield - display FP field** RETURNS: N/A** NOMANUAL**/LOCAL void fp_mfield    (    UINT32	instr    )    {    UINT32 r = bits(0,2);    if (bit(3))	{	if (r < 6)	    outi(r);	else	    outs((r == 6 ? "#0.5" : "#10"));	}    else	freg(r, 0);    return;    } /* fp_mfield() *//********************************************************************************* fp_cpdo - display FP op** RETURNS: N/A** NOMANUAL**/LOCAL void fp_cpdo    (    UINT32	instr,    BOOL *	oddity    )    {    char *opset;    int l;    if (bit(15))  /* unary */	opset = "MVF\0MNF\0ABS\0RND\0SQT\0LOG\0LGN\0EXP\0"		"SIN\0COS\0TAN\0ASN\0ACS\0ATN\0URD\0NRM";    else	opset = "ADF\0MUF\0SUF\0RSF\0DVF\0RDF\0POW\0RPW\0"		"RMF\0FML\0FDV\0FRD\0POL\0XX1\0XX2\0XX3";    l = outs(opset + 4*bits(20,23));    l += cond(instr);    outc(fp_widthname(instr));    l++;    l += outs(fp_rounding(instr));    spacetocol9(l);    freg(bits(12,14), ',');  /* Fd */    if (!bit(15))	freg(bits(16,18), ',');  /* Fn */    else	if (bits(16,18) != 0)	    /* odd monadic (Fn != 0) ... */	    *oddity = TRUE;    fp_mfield(instr);    return;    } /* fp_cpdo() *//********************************************************************************* fp_cprt - display floating-point register transfer instruction** RETURNS: N/A** NOMANUAL**/LOCAL void fp_cprt    (    UINT32	instr    )    {    int op = (int)bits(20,23);    if (bits(12,15) == 15)  /* ARM register = pc */	{	if ((op & 9) != 9)	    op = 4;	else	    op = (op>>1)-4;	opcode(instr, "CMF\0\0CNF\0\0CMFE\0CNFE\0???" + 5*op, 0);	freg(bits(16,18), ',');	fp_mfield(instr);	return;	}    else	{	int l;	if (op > 7)	    op = 7;	l = outs("FLT\0FIX\0WFS\0RFS\0WFC\0RFC\0???\0???" + 4*op);	l += cond(instr);	outc(fp_widthname(instr));	l++;	l += outs(fp_rounding(instr));	spacetocol9(l);	if (bits(20,23) == 0) /* FLT */	    {	    freg(bits(16,18), ',');	    }	reg(bits(12,15), 0);	if (bits(20,23) == 1) /* FIX */	   {	   outc(',');	   fp_mfield(instr);	   }	}    return;    } /* fp_cprt() *//********************************************************************************* fp_cpdt - display floating-point data transfer instruction** RETURNS: N/A** NOMANUAL**/LOCAL void fp_cpdt    (    UINT32	instr,    UINT32	address,    VOIDFUNCPTR	prtAddress    )    {    if (!bit(24) && !bit(21))	{	/* oddity: post and not writeback */	generic_cpdt(instr, address, prtAddress);	}    else	{	opcode(instr, (bit(20) ? "LDF" : "STF"), fp_dt_widthname(instr));	freg(bits(12,14), ',');	outAddress(instr, address, 4*bits(0,7), prtAddress);	}    return;    } /* fp_cpdt() *//********************************************************************************* fm_cpdt - display floating-point load/store multiple instruction** RETURNS: N/A** NOMANUAL**/LOCAL void fm_cpdt    (    UINT32	instr,    UINT32	address,    VOIDFUNCPTR	prtAddress    )    {    if (!bit(24) && !bit(21))	{	/* oddity: post and not writeback */	generic_cpdt(instr, address, prtAddress);	return;	}    opcode(instr, (bit(20) ? "LFM" : "SFM"), 0);    freg(bits(12,14), ',');    {	int count = (int)(bit(15) + 2*bit(22));	outf("%d,", count==0 ? 4: count);    }    outAddress(instr, address, 4*bits(0,7), prtAddress);    return;    } /* fm_cpdt() *//********************************************************************************* disass_32 - disassemble an ARM (32-bit) instruction** RETURNS: size of instruction, in bytes** NOMANUAL**/LOCAL UINT32 disass_32    (    UINT32	instr,		/* the value of the instruction */    UINT32	address,	/* the address to print before instruction */    VOIDFUNCPTR	prtAddress	/* routine to print addresses as symbols */    )    {    BOOL oddity = FALSE;    switch (bits(24,27))	{	case 0:	    if (bit(23) == 1 && bits(4,7) == 9)		{ /* Long Multiply */		opcode(instr, bit(21) ? (bit(22) ? "SMLAL" : "UMLAL")		                      : (bit(22) ? "SMULL" : "UMULL"),		       bit(20) ? 'S' : 0);

⌨️ 快捷键说明

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