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

📄 dis16.c

📁 mips架构的bootloader,99左右的版本 但源代码现在没人更新了
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************* * File: dis16.c * Purpose: disassembler for mips16 * Author: Phil Bunce (pjb@carmel.com) * Revision History: *	970505	Created *	980107	Corrected typedef for dis16fmt *	980715	Fixed for -EL mips16 *	990107	Fixed prob with extended instrs *	990303	Fixed disassembly of lbu */#include <mon.h>#include <stdio.h>#define RXN(i) 	(((i)>>8)&7)#define RYN(i) 	(((i)>>5)&7)#define RZN(i) 	(((i)>>2)&7)#define R32AN(i) 	(((i)>>0)&0x1f)#define R32BN(i) 	(((i)&0x18)|((i)>>5)&7)#define RX(i)	gp16regs[RXN(i)]#define RY(i)	gp16regs[RYN(i)]#define RZ(i)	gp16regs[RZN(i)]#define SA(i)	((((i)>>2)&7)?(((i)>>2)&7):8)#define R32A(i) gp32regs[R32AN(i)]#define R32B(i) gp32regs[R32BN(i)]typedef enum {	RA_O_SP, RX_O_SP, RY_O_RX1, RY_O_RX2, RX_O_PC, RX_I8, RX_UI8,	RX_PC_I8, RX_SP_I8, RY_RX_I4, SP_I8, RZ_RX_RY, R32B_RZ,	RY_R32A, RX_RY_SA, JAL_TARG, RX_RY, OFFSET8_ONLY, RY_I5,	RY_PC_I5, RY_SP_I5, RY_O_SP3, RY_O_RX3, RY_O_PC, RY_O_RX0,	RX_ONLY, RA_ONLY, RA_RX, OFFSET11_ONLY, RX_OFFSET, IMM6_ONLY,	RY_RX, RY_SA, NO_OPS, JALX_TARG, JR_RX } dis16fmt;enum { SIMM4, SIMM5, UIMM5, UIMM8, SIMM8, SIMM11, SIMM15, UIMM16,	SIMM16, SIMM16S};typedef struct Dis16Rec {	char *name;	Ulong mask;	Ulong val;	int fmt;	} Dis16Rec;Dis16Rec dis16tbl[] = {	{"jal",	  0xfc00,0x1800,JAL_TARG},	{"jalx",  0xfc00,0x1c00,JALX_TARG},	{"nop",	  0xffff,0x6500,NO_OPS}, 	{"addiu", 0xf800,0x0000,RX_SP_I8}, /* rx, sp, imm8 */	{"addiu", 0xf800,0x0800,RX_PC_I8}, /* rx, pc, imm8 */	{"addiu", 0xf800,0x4800,RX_I8}, /* rx, imm8 */	{"addiu", 0xf810,0x4000,RY_RX_I4}, /* ry, rx, imm4 */	{"addiu", 0xff00,0x6300,SP_I8}, /* sp, imm8 */	{"addu",  0xf803,0xe001,RZ_RX_RY}, /* rz,rx,ry */	{"and",	  0xf81f,0xe80c,RX_RY},	{"b",	  0xf800,0x1000,OFFSET11_ONLY},	{"beqz",  0xf800,0x2000,RX_OFFSET},	{"bnez",  0xf800,0x2800,RX_OFFSET},	{"break", 0xf81f,0xe805,IMM6_ONLY},	{"bteqz", 0xff00,0x6000,OFFSET8_ONLY},	{"btnez", 0xff00,0x6100,OFFSET8_ONLY},	{"cmp",	  0xf800,0x7000,RX_I8},	{"cmp",	  0xf81f,0xe80a,RX_RY},#if 0 /* 64-bit */	{"daddiu",0xf810,0x4010,RY_RX_I4},	{"daddiu",0xff00,0xfb00,SP_I8},	{"daddiu",0xff00,0xfd00,RY_I5},	{"daddiu",0xff00,0xfe00,RY_PC_I5},	{"daddiu",0xff00,0xff00,RY_SP_I5},	{"daddu", 0xf803,0xe000,RZ_RX_RY},	{"ddiv",  0xf81f,0xe81e,RX_RY},	{"ddivu", 0xf81f,0xe81f,RX_RY},	{"dmult", 0xf81f,0xe81c,RX_RY},	{"dmultu",0xf81f,0xe81d,RX_RY},	{"dsll",  0xf803,0x3001,RX_RY_SA},	{"dsll",  0xf81f,0xe814,RY_RX},	{"dsra",  0xf81f,0xe813,RY_SA},	{"dsra",  0xf81f,0xe817,RY_RX},	{"dsrl",  0xf81f,0xe808,RY_SA},	{"dsrl",  0xf81f,0xe816,RY_RX},	{"dsubu", 0xf803,0xe002,RZ_RX_RY},	{"lwu",	  0xf800,0xb800,RY_O_RX2}, /* ry,off(rx) */	{"ld",	  0xf800,0x3800,RY_O_RX3},	{"ld",	  0xff00,0xf800,RY_O_SP3},	{"ld",	  0xff00,0xfc00,RY_O_PC},	{"sd",	  0xff00,0xfa00,RA_O_SP},	{"sd",	  0xf800,0x7800,RY_O_RX3},	{"sd",	  0xff00,0xf900,RY_O_SP3},#endif	{"div",	  0xf81f,0xe81a,RX_RY},	{"divu",  0xf81f,0xe81b,RX_RY},	{"jalr",  0xf8ff,0xe840,RA_RX},	{"jr",	  0xf8ff,0xe800,JR_RX},	{"jr",	  0xffff,0xe820,RA_ONLY},	{"lb",	  0xf800,0x8000,RY_O_RX0},	{"lh",	  0xf800,0x8800,RY_O_RX1}, /* ry,off(rx) */	{"lbu",	  0xf800,0xa000,RY_O_RX0},	{"lhu",	  0xf800,0xa800,RY_O_RX1}, /* ry,off(rx) */	{"li",	  0xf800,0x6800,RX_UI8},	{"lw",	  0xf800,0x9000,RX_O_SP}, /* rx,off(sp) */	{"lw",	  0xf800,0x9800,RY_O_RX2}, /* ry,off(rx) */	{"lw",	  0xf800,0xb000,RX_O_PC}, /* rx,off(pc) */	{"mfhi",  0xf8ff,0xe810,RX_ONLY},	{"mflo",  0xf8ff,0xe812,RX_ONLY},	{"mult",  0xf81f,0xe818,RX_RY},	{"multu", 0xf81f,0xe819,RX_RY},	{"move",  0xff00,0x6500,R32B_RZ},	{"move",  0xff00,0x6700,RY_R32A},	{"neg",	  0xf81f,0xe80b,RX_RY},	{"not",	  0xf81f,0xe80f,RX_RY},	{"or",	  0xf81f,0xe80d,RX_RY},	{"sb",	  0xf800,0xc000,RY_O_RX0}, /* ry,off(rx) */	{"sh",	  0xf800,0xc800,RY_O_RX1}, /* ry,off(rx) */	{"sll",	  0xf803,0x3000,RX_RY_SA},	{"sllv",  0xf81f,0xe804,RY_RX},	{"slt",	  0xf81f,0xe802,RX_RY},	{"slti",  0xf800,0x5000,RX_I8},	{"sltiu", 0xf800,0x5800,RX_I8},	{"sltu",  0xf81f,0xe803,RX_RY},	{"sra",	  0xf803,0x3003,RX_RY_SA},	{"srav",  0xf81f,0xe807,RY_RX},	{"srl",	  0xf803,0x3002,RX_RY_SA},	{"srlv",  0xf81f,0xe806,RY_RX},	{"subu",  0xf803,0xe803,RZ_RX_RY},	{"sw",	  0xff00,0x6200,RA_O_SP}, /* ra,off(sp) */	{"sw",	  0xf800,0xd000,RX_O_SP}, /* rx,off(sp) */	{"sw",	  0xf800,0xd800,RY_O_RX2}, /* ry,off(rx) */	{"xor",	  0xf81f,0xe80e,RX_RY},	{0}};char *gp16regs[] = {"s0","s1","v0","v1","a0","a1","a2","a3"};char gp16regNum[] = {16,17,2,3,4,5,6,7};char *gp32regs[] = {"zero","AT","v0","v1","a0","a1","a2","a3","t0,","t1","t2","t3","t4","t5","t6","t7","s0","s1","s2","s3","s4","s5","s5","s6","s7","t8","t9","k0","k1","gp","sp", "s8","ra"};static Ulong imm();static Ulong sgnext();#define swap_halves(v) ((((Ulong)(v))>>16)&0xffff) | \			((((Ulong)(v))<<16)&0xffff0000);/* hw0 and hw1 are for accessing half-word zero and half-word on.* Half-word zero is always the first read from memory (ie the occupying* the lowest numbered address).*/#ifdef MIPSEB#define hw0(v)   (((Ulong)(v))>>16)#define hw1(v)   (((Ulong)(v))&0xffff)#else#define hw0(v)   (((Ulong)(v))&0xffff)#define hw1(v)   (((Ulong)(v))>>16)#endifstatic Ulong getInst(Ulong instr);static int mips16_32bit_instr(Ulong instr);static Dis16Rec *getDis16Rec(Ulong instr);static Ulong get16Gpr(int n);/**************************************************************/Ulong dis16(prnbuf,addr,wd)char *prnbuf;Ulong addr,wd;{int n,sz,extended;char tmp[200];Ulong im,vaddr,instr;Dis16Rec *t;vaddr = addr&~1;instr = getInst(wd);extended = 0;if (mips16_32bit_instr(wd)) {	addr += 2;	sprintf(tmp," %04x%04x ",hw0(wd),hw1(wd));	extended = 1;	}else sprintf(tmp," %04x     ",instr);strcat(prnbuf,tmp);if ((t=getDis16Rec(wd))==0) {	sprintf(tmp,".half   %04x",instr);	strcat(prnbuf,tmp);	return(addr+2);	}n = strlen(t->name);strcat(prnbuf,t->name);while(n++ < 8) strcat(prnbuf," ");switch (t->fmt) {	case NO_OPS : *tmp=0; break;	case RY_I5:		im = imm(instr,(!extended)?SIMM5:SIMM16,wd,0);		sprintf(tmp,"%s,%d",RY(instr),im);		strcat(prnbuf,tmp); *tmp = 0;		mkcomment(prnbuf,"# 0x%08lx",im);		break;	case RY_PC_I5:		im = imm(instr,(!extended)?UIMM5:UIMM16,wd,2);		sprintf(tmp,"%s,pc,%d",RY(instr),im);		strcat(prnbuf,tmp); *tmp = 0;		mkcomment(prnbuf,"# 0x%08lx",vaddr+im);		break;	case RY_SP_I5:		im = imm(instr,(!extended)?UIMM5:UIMM16,wd,2);		sprintf(tmp,"%s,sp,%d",RY(instr),im);		strcat(prnbuf,tmp); *tmp = 0;		mkcomment(prnbuf,"# 0x%08lx",im);		break;	case IMM6_ONLY:		im = (instr>>5)&0x3f;		sprintf(tmp,"%d",im);		break;	case RX_RY:		sprintf(tmp,"%s,%s",RX(instr),RY(instr));		break;	case RA_RX:		sprintf(tmp,"ra,%s",RX(instr));		break;	case RA_ONLY:		sprintf(tmp,"ra");		break;	case RX_ONLY:	case JR_RX :		sprintf(tmp,"%s",RX(instr));		break;	case JAL_TARG:		im = ((hw0(wd)&0x1f)<<21)| ((hw0(wd)&0x3e0)<<(16-5))| hw1(wd);		im = (vaddr&0xf0000000)|(im<<2);		if (!adr2symoff(tmp,im+1,0)) sprintf(tmp,"%x",im);		strcat(prnbuf,tmp); *tmp = 0;		mkcomment(prnbuf,"# 0x%08lx",im);		break;	case JALX_TARG:		im = ((hw0(wd)&0x1f)<<21)| ((hw0(wd)&0x3e0)<<(16-5))| hw1(wd);		im = (vaddr&0xf0000000)|(im<<2);		if (!adr2symoff(tmp,im,0)) sprintf(tmp,"%x",im);		strcat(prnbuf,tmp); *tmp = 0;		mkcomment(prnbuf,"# 0x%08lx",im);		break;	case RX_RY_SA:		sprintf(tmp,"%s,%s,%d",RX(instr),RY(instr),SA(instr));		break;	case RY_SA:		sprintf(tmp,"%s,%d",RY(instr),SA(instr));		break;	/* ry,im,rx */	case RY_O_RX0:		im = imm(instr,(!extended)?UIMM5:SIMM16,wd,0);		sprintf(tmp,"%s,%d(%s)",RY(instr),im,RX(instr));		break;	case RY_O_RX1:		im = imm(instr,(!extended)?UIMM5:SIMM16,wd,1);		sprintf(tmp,"%s,%d(%s)",RY(instr),im,RX(instr));		break;	case RY_O_RX2:		im = imm(instr,(!extended)?UIMM5:SIMM16,wd,2);		sprintf(tmp,"%s,%d(%s)",RY(instr),im,RX(instr));		break;	case RY_O_RX3:		im = imm(instr,(!extended)?UIMM5:SIMM16,wd,3);		sprintf(tmp,"%s,%d(%s)",RY(instr),im,RX(instr));		break;	/* rx,im,im */	case RX_OFFSET: /* RX_IM_IM, SIMM8, SIMM16S, 1, $addr+2 */		sz = instr_size(addr,instr);		im = vaddr+sz+imm(instr,(!extended)?SIMM8:SIMM16S,wd,1);		sprintf(tmp,"%s,",RX(instr));		strcat(prnbuf,tmp);		if (!adr2symoff(tmp,im+1,0)) sprintf(tmp,"%x",im);		strcat(prnbuf,tmp); *tmp = 0;		mkcomment(prnbuf,"# 0x%08lx",im);		break;	case RY_O_SP3:		im = imm(instr,(!extended)?UIMM8:SIMM16,wd,3);		sprintf(tmp,"%s,%d(sp)",RY(instr),im);		break;	case RX_O_SP:		im = imm(instr,(!extended)?UIMM8:SIMM16,wd,2);		sprintf(tmp,"%s,%d(sp)",RX(instr),im);		break;	case RX_I8:		im = imm(instr,(!extended)?SIMM8:UIMM16,wd,0);		sprintf(tmp,"%s,%d",RX(instr),im);		strcat(prnbuf,tmp); *tmp = 0;		mkcomment(prnbuf,"# 0x%08lx",im);		break;	case RX_UI8:		im = imm(instr,(!extended)?UIMM8:UIMM16,wd,0);		sprintf(tmp,"%s,%d",RX(instr),im);		strcat(prnbuf,tmp); *tmp = 0;		mkcomment(prnbuf,"# 0x%08lx",im);		break;	case RX_SP_I8:		im = imm(instr,(!extended)?UIMM8:UIMM16,wd,2);		sprintf(tmp,"%s,sp,%d",RX(instr),im);		strcat(prnbuf,tmp); *tmp = 0;		mkcomment(prnbuf,"# 0x%08lx",im);		break;	/* ry,rx,im */	case RY_RX_I4:		im = imm(instr,(!extended)?SIMM4:SIMM15,wd,0);		sprintf(tmp,"%s,%s,%d",RY(instr),RX(instr),im);		break;	/* rx,im,addr+im */	case RY_O_PC:		im = imm(instr,(!extended)?UIMM8:SIMM16,wd,2);		sprintf(tmp,"%s,%d(pc)",RY(instr),im);		strcat(prnbuf,tmp); *tmp = 0;		mkcomment(prnbuf,"# 0x%08lx",vaddr+im);		break;	case RX_O_PC:		im = imm(instr,(!extended)?UIMM8:SIMM16,wd,2);		sprintf(tmp,"%s,%d(pc)",RX(instr),im);		strcat(prnbuf,tmp); *tmp = 0;

⌨️ 快捷键说明

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