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

📄 vcodas.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include <mach.h>	/* mips native disassembler */typedef struct {	uvlong addr;			/* pc of instr */	uchar op;			/* bits 31-26 */	uchar rs;			/* bits 25-21 */	uchar rt;			/* bits 20-16 */	uchar rd;			/* bits 15-11 */	uchar sa;			/* bits 10-6 */	uchar function;			/* bits 5-0 */	long immediate;			/* bits 15-0 */	ulong cofun;			/* bits 24-0 */	ulong target;			/* bits 25-0 */	long w0;	char *curr;			/* current fill point */	char *end;			/* end of buffer */	char *err;} Instr;typedef struct {	char *mnemonic;	char *mipsco;} Opcode;static char mipscoload[] = "r%t,%l";static char mipscoalui[] = "r%t,r%s,%i";static char mipscoalu3op[] = "r%d,r%s,r%t";static char mipscoboc[] = "r%s,r%t,%b";static char mipscoboc0[] = "r%s,%b";static char mipscorsrt[] = "r%s,r%t";static char mipscorsi[] = "r%s,%i";static char mipscoxxx[] = "%w";static char mipscofp3[] = "f%a,f%d,f%t";	/* fd,fs,ft */static char mipscofp2[] = "f%a,f%d";		/* fd,fs */static char mipscofpc[] = "f%d,f%t";		/* fs,ft */static Opcode opcodes[64] = {	0,		0,	0,		0,	"j",		"%j",	"jal",		"%j",	"beq",		mipscoboc,	"bne",		mipscoboc,	"blez",		mipscoboc0,	"bgtz",		mipscoboc0,	"addi",		mipscoalui,	"addiu",	mipscoalui,	"slti",		mipscoalui,	"sltiu",	mipscoalui,	"andi",		mipscoalui,	"ori",		mipscoalui,	"xori",		mipscoalui,	"lui",		"r%t,%u",	"cop0",		0,	"cop1",		0,	"cop2",		0,	"cop3",		0,	"beql",		mipscoboc,	"bnel",		mipscoboc,	"blezl",	mipscoboc0,	"bgtzl",	mipscoboc0,	"instr18",	mipscoxxx,	"instr19",	mipscoxxx,	"instr1A",	mipscoxxx,	"instr1B",	mipscoxxx,	"instr1C",	mipscoxxx,	"instr1D",	mipscoxxx,	"instr1E",	mipscoxxx,	"instr1F",	mipscoxxx,	"lb",		mipscoload,	"lh",		mipscoload,	"lwl",		mipscoload,	"lw",		mipscoload,	"lbu",		mipscoload,	"lhu",		mipscoload,	"lwr",		mipscoload,	"instr27",	mipscoxxx,	"sb",		mipscoload,	"sh",		mipscoload,	"swl",		mipscoload,	"sw",		mipscoload,	"instr2C",	mipscoxxx,	"instr2D",	mipscoxxx,	"swr",		mipscoload,	"cache",	"",	"ll",		mipscoload,	"lwc1",		mipscoload,	"lwc2",		mipscoload,	"lwc3",		mipscoload,	"instr34",	mipscoxxx,	"ld",		mipscoload,	"ld",		mipscoload,	"ld",		mipscoload,	"sc",		mipscoload,	"swc1",		mipscoload,	"swc2",		mipscoload,	"swc3",		mipscoload,	"instr3C",	mipscoxxx,	"sd",		mipscoload,	"sd",		mipscoload,	"sd",		mipscoload,};static Opcode sopcodes[64] = {	"sll",		"r%d,r%t,$%a",	"special01",	mipscoxxx,	"srl",		"r%d,r%t,$%a",	"sra",		"r%d,r%t,$%a",	"sllv",		"r%d,r%t,R%s",	"special05",	mipscoxxx,	"srlv",		"r%d,r%t,r%s",	"srav",		"r%d,r%t,r%s",	"jr",		"r%s",	"jalr",		"r%d,r%s",	"special0A",	mipscoxxx,	"special0B",	mipscoxxx,	"syscall",	"",	"break",	"",	"special0E",	mipscoxxx,	"sync",		"",	"mfhi",		"r%d",	"mthi",		"r%s",	"mflo",		"r%d",	"mtlo",		"r%s",	"special14",	mipscoxxx,	"special15",	mipscoxxx,	"special16",	mipscoxxx,	"special17",	mipscoxxx,	"mult",		mipscorsrt,	"multu",	mipscorsrt,	"div",		mipscorsrt,	"divu",		mipscorsrt,	"special1C",	mipscoxxx,	"special1D",	mipscoxxx,	"special1E",	mipscoxxx,	"special1F",	mipscoxxx,	"add",		mipscoalu3op,	"addu",		mipscoalu3op,	"sub",		mipscoalu3op,	"subu",		mipscoalu3op,	"and",		mipscoalu3op,	"or",		mipscoalu3op,	"xor",		mipscoalu3op,	"nor",		mipscoalu3op,	"special28",	mipscoxxx,	"special29",	mipscoxxx,	"slt",		mipscoalu3op,	"sltu",		mipscoalu3op,	"special2C",	mipscoxxx,	"special2D",	mipscoxxx,	"special2E",	mipscoxxx,	"special2F",	mipscoxxx,	"tge",		mipscorsrt,	"tgeu",		mipscorsrt,	"tlt",		mipscorsrt,	"tltu",		mipscorsrt,	"teq",		mipscorsrt,	"special35",	mipscoxxx,	"tne",		mipscorsrt,	"special37",	mipscoxxx,	"special38",	mipscoxxx,	"special39",	mipscoxxx,	"special3A",	mipscoxxx,	"special3B",	mipscoxxx,	"special3C",	mipscoxxx,	"special3D",	mipscoxxx,	"special3E",	mipscoxxx,	"special3F",	mipscoxxx,};static Opcode ropcodes[32] = {	"bltz",		mipscoboc0,	"bgez",		mipscoboc0,	"bltzl",	mipscoboc0,	"bgezl",	mipscoboc0,	"regimm04",	mipscoxxx,	"regimm05",	mipscoxxx,	"regimm06",	mipscoxxx,	"regimm07",	mipscoxxx,	"tgei",		mipscorsi,	"tgeiu",	mipscorsi,	"tlti",		mipscorsi,	"tltiu",	mipscorsi,	"teqi",		mipscorsi,	"regimm0D",	mipscoxxx,	"tnei",		mipscorsi,	"regimm0F",	mipscoxxx,	"bltzal",	mipscoboc0,	"bgezal",	mipscoboc0,	"bltzall",	mipscoboc0,	"bgezall",	mipscoboc0,	"regimm14",	mipscoxxx,	"regimm15",	mipscoxxx,	"regimm16",	mipscoxxx,	"regimm17",	mipscoxxx,	"regimm18",	mipscoxxx,	"regimm19",	mipscoxxx,	"regimm1A",	mipscoxxx,	"regimm1B",	mipscoxxx,	"regimm1C",	mipscoxxx,	"regimm1D",	mipscoxxx,	"regimm1E",	mipscoxxx,	"regimm1F",	mipscoxxx,};static Opcode fopcodes[64] = {	"add.%f",	mipscofp3,	"sub.%f",	mipscofp3,	"mul.%f",	mipscofp3,	"div.%f",	mipscofp3,	"sqrt.%f",	mipscofp2,	"abs.%f",	mipscofp2,	"mov.%f",	mipscofp2,	"neg.%f",	mipscofp2,	"finstr08",	mipscoxxx,	"finstr09",	mipscoxxx,	"finstr0A",	mipscoxxx,	"finstr0B",	mipscoxxx,	"round.w.%f",	mipscofp2,	"trunc.w%f",	mipscofp2,	"ceil.w%f",	mipscofp2,	"floor.w%f",	mipscofp2,	"finstr10",	mipscoxxx,	"finstr11",	mipscoxxx,	"finstr12",	mipscoxxx,	"finstr13",	mipscoxxx,	"finstr14",	mipscoxxx,	"finstr15",	mipscoxxx,	"finstr16",	mipscoxxx,	"finstr17",	mipscoxxx,	"finstr18",	mipscoxxx,	"finstr19",	mipscoxxx,	"finstr1A",	mipscoxxx,	"finstr1B",	mipscoxxx,	"finstr1C",	mipscoxxx,	"finstr1D",	mipscoxxx,	"finstr1E",	mipscoxxx,	"finstr1F",	mipscoxxx,	"cvt.s.%f",	mipscofp2,	"cvt.d.%f",	mipscofp2,	"cvt.e.%f",	mipscofp2,	"cvt.q.%f",	mipscofp2,	"cvt.w.%f",	mipscofp2,	"finstr25",	mipscoxxx,	"finstr26",	mipscoxxx,	"finstr27",	mipscoxxx,	"finstr28",	mipscoxxx,	"finstr29",	mipscoxxx,	"finstr2A",	mipscoxxx,	"finstr2B",	mipscoxxx,	"finstr2C",	mipscoxxx,	"finstr2D",	mipscoxxx,	"finstr2E",	mipscoxxx,	"finstr2F",	mipscoxxx,	"c.f.%f",	mipscofpc,	"c.un.%f",	mipscofpc,	"c.eq.%f",	mipscofpc,	"c.ueq.%f",	mipscofpc,	"c.olt.%f",	mipscofpc,	"c.ult.%f",	mipscofpc,	"c.ole.%f",	mipscofpc,	"c.ule.%f",	mipscofpc,	"c.sf.%f",	mipscofpc,	"c.ngle.%f",	mipscofpc,	"c.seq.%f",	mipscofpc,	"c.ngl.%f",	mipscofpc,	"c.lt.%f",	mipscofpc,	"c.nge.%f",	mipscofpc,	"c.le.%f",	mipscofpc,	"c.ngt.%f",	mipscofpc,};static char fsub[16] = {	's', 'd', 'e', 'q', 'w', '?', '?', '?',	'?', '?', '?', '?', '?', '?', '?', '?'};static intmkinstr(Instr *i, Map *map, uvlong pc){	ulong w;	if (get4(map, pc, &w) < 0) {		werrstr("can't read instruction: %r");		return -1;	}	i->addr = pc;	i->op = (w >> 26) & 0x3F;	i->rs = (w >> 21) & 0x1F;	i->rt = (w >> 16) & 0x1F;	i->rd = (w >> 11) & 0x1F;	i->sa = (w >> 6) & 0x1F;	i->function = w & 0x3F;	i->immediate = w & 0x0000FFFF;	if (i->immediate & 0x8000)		i->immediate |= ~0x0000FFFF;	i->cofun = w & 0x01FFFFFF;	i->target = w & 0x03FFFFFF;	i->w0 = w;	return 1;}#pragma	varargck	argpos	bprint		2static voidbprint(Instr *i, char *fmt, ...){	va_list arg;	va_start(arg, fmt);	i->curr = vseprint(i->curr, i->end, fmt, arg);	va_end(arg);}static voidformat(char *mnemonic, Instr *i, char *f){	if (mnemonic)		format(0, i, mnemonic);	if (f == 0)		return;	if (i->curr < i->end)		*i->curr++ = '\t';	for ( ; *f && i->curr < i->end; f++) {		if (*f != '%') {			*i->curr++ = *f;			continue;		}		switch (*++f) {		case 's':			bprint(i, "%d", i->rs);			break;		case 't':			bprint(i, "%d", i->rt);			break;		case 'd':			bprint(i, "%d", i->rd);			break;		case 'a':			bprint(i, "%d", i->sa);			break;		case 'l':			if (i->rs == 30) {				i->curr += symoff(i->curr, i->end-i->curr, i->immediate+mach->sb, CANY);				bprint(i, "(SB)");			} else 				bprint(i, "%lx(r%d)", i->immediate, i->rs);			break;		case 'i':			bprint(i, "$%lx", i->immediate);			break;		case 'u':			*i->curr++ = '$';			i->curr += symoff(i->curr, i->end-i->curr, i->immediate, CANY);			bprint(i, "(SB)");			break;		case 'j':			i->curr += symoff(i->curr, i->end-i->curr,				(i->target<<2)|(i->addr & 0xF0000000), CANY);			bprint(i, "(SB)");			break;		case 'b':			i->curr += symoff(i->curr, i->end-i->curr,				(i->immediate<<2)+i->addr+4, CANY);			break;		case 'c':			bprint(i, "%lux", i->cofun);			break;		case 'w':			bprint(i, "[%lux]", i->w0);			break;		case 'f':			*i->curr++ = fsub[i->rs & 0x0F];			break;		case '\0':			*i->curr++ = '%';			return;		default:			bprint(i, "%%%c", *f);			break;		}	}}static voidcopz(int cop, Instr *i){	char *f, *m, buf[16];	m = buf;	f = "%t,%d";	switch (i->rs) {	case 0:		sprint(buf, "mfc%d", cop);		break;	case 2:		sprint(buf, "cfc%d", cop);		break;	case 4:		sprint(buf, "mtc%d", cop);		break;	case 6:		sprint(buf, "ctc%d", cop);		break;	case 8:		f = "%b";		switch (i->rt) {		case 0:			sprint(buf, "bc%df", cop);			break;		case 1:			sprint(buf, "bc%dt", cop);			break;		case 2:			sprint(buf, "bc%dfl", cop);			break;		case 3:			sprint(buf, "bc%dtl", cop);			break;		default:			sprint(buf, "cop%d", cop);			f = mipscoxxx;			break;		}		break;	default:		sprint(buf, "cop%d", cop);		if (i->rs & 0x10)			f = "function %c";		else			f = mipscoxxx;		break;	}	format(m, i, f);}static voidcop0(Instr *i){	char *m = 0;	if (i->rs >= 0x10) {		switch (i->cofun) {			case 1:			m = "tlbr";			break;			case 2:			m = "tlbwi";			break;			case 6:			m = "tlbwr";			break;			case 8:			m = "tlbp";			break;			case 16:			m = "rfe";			break;			case 32:			m = "eret";			break;		}		if (m) {			format(m, i, 0);			if (i->curr < i->end)				*i->curr++ = 0;			return;		}	}	copz(0, i);}int_mipscoinst(Map *map, uvlong pc, char *buf, int n){	Instr i;	Opcode *o;	uchar op;	i.curr = buf;	i.end = buf+n-1;	if (mkinstr(&i, map, pc) < 0)		return -1;	switch (i.op) {	case 0x00:					/* SPECIAL */		o = sopcodes;		op = i.function;		break;	case 0x01:					/* REGIMM */		o = ropcodes;		op = i.rt;		break;	case 0x10:					/* COP0 */		cop0(&i);		return 4;	case 0x11:					/* COP1 */		if (i.rs & 0x10) {			o = fopcodes;			op = i.function;			break;		}		/*FALLTHROUGH*/	case 0x12:					/* COP2 */	case 0x13:					/* COP3 */		copz(i.op-0x10, &i);		return 4;	default:		o = opcodes;		op = i.op;		break;	}	format(o[op].mnemonic, &i, o[op].mipsco);	return 4;}

⌨️ 快捷键说明

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