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

📄 2db.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 4 页
字号:
	{	case 0x10:		break;	case 0x20:		if (i16(ip, &ap->disp) < 0)			return -1;		break;	case 0x30:		if (i32(ip, &ap->disp) < 0)			return -1;		break;	default:		ip->errmsg = "bad EA displacement";		return -1;	}	switch (ext&0x03)	/* outer displacement */	{	case 0x02:		/* 16 bit displacement */		return i16(ip, &ap->outer);	case 0x03:		/* 32 bit displacement */		return i32(ip, &ap->outer);	default:		break;	}	return 1;}static intea(Inst *ip, int ea, Operand *ap, int mode){	int type, size;	type = 0;	ap->ext = 0;	switch((ea>>3)&0x07)	{	case 0x00:		ap->eatype = Dreg;		type = Dn;		break;	case 0x01:		ap->eatype = Areg;		type = An;		break;	case 0x02:		ap->eatype = AInd;		type = Ind;		break;	case 0x03:		ap->eatype = APinc;		type = Pinc;		break;	case 0x04:		ap->eatype = APdec;		type = Pdec;		break;	case 0x05:		ap->eatype = ADisp;		type = Bdisp;		if (i16(ip, &ap->disp) < 0)			return -1;		break;	case 0x06:		ap->eatype = BXD;		type = Bdisp;		if (getdisp(ip, ap) < 0)			return -1;		break;	case 0x07:		switch(ea&0x07)		{		case 0x00:			type = Abs;			ap->eatype = ABS;			if (i16(ip, &ap->immediate) < 0)				return -1;			break;		case 0x01:			type = Abs;			ap->eatype = ABS;			if (i32(ip, &ap->immediate) < 0)				return -1;			break;		case 0x02:			type = PCrel;			ap->eatype = PDisp;			if (i16(ip, &ap->disp) < 0)				return -1;			break;		case 0x03:			type = PCrel;			ap->eatype = PXD;			if (getdisp(ip, ap) < 0)				return -1;			break;		case 0x04:			type = Imm;			if (getimm(ip, ap, mode) < 0)				return -1;			break;		default:			ip->errmsg = "bad EA mode";			return -1;		}	}		/* Allowable floating point EAs are restricted for packed,		 * extended, and double precision operands		 */	if (mode == EAFLT) {		size = (ip->raw[1]>>10)&0x07;		if (size == 2 || size == 3 || size == 5)			mode = EAM;		else			mode = EADI;	}	if (!(validea[mode]&type)) {		ip->errmsg = "invalid EA";		return -1;	}	return 1;}static intdecode(Inst *ip, Optable *op){	int i, t, mode;	Operand *ap;	short opcode;	opcode = ip->raw[0];	for (i = 0; i < nelem(op->opdata) && op->opdata[i]; i++) {		ap = &ip->and[i];		mode = op->opdata[i];		switch(mode)		{		case EAPI:		/* normal EA modes */		case EACA:		case EACAD:		case EACAPI:		case EACAPD:		case EAMA:		case EADA:		case EAA:		case EAC:		case EACPI:		case EACD:		case EAD:		case EAM:		case EAM_B:		case EADI:		case EADI_L:		case EADI_W:		case EAALL:		case EAALL_L:		case EAALL_W:		case EAALL_B:		case EAFLT:			if (ea(ip, opcode&0x3f, ap, mode) < 0)				return -1;			break;		case EADDA:	/* stupid bit flop required */			t = ((opcode>>9)&0x07)|((opcode>>3)&0x38);			if (ea(ip, t, ap, EADA)< 0)					return -1;			break;		case BREAC:	/* EAC JMP or CALL operand */			if (ea(ip, opcode&0x3f, ap, EAC) < 0)				return -1;			break;		case OP8:	/* weird movq instruction */			ap->eatype = IMM;			ap->immediate = opcode&0xff;			if (opcode&0x80)				ap->immediate |= ~0xff;			break;		case I8:	/* must be two-word opcode */			ap->eatype = IMM;			ap->immediate = ip->raw[1]&0xff;			if (ap->immediate&0x80)				ap->immediate |= ~0xff;			break;		case I16:	/* 16 bit immediate */		case BR16:			ap->eatype = IMM;			if (i16(ip, &ap->immediate) < 0)				return -1;			break;		case C16:	/* CAS2 16 bit immediate */			ap->eatype = IMM;			if (i16(ip, &ap->immediate) < 0)				return -1;			if (ap->immediate & 0x0e38) {				ip->errmsg = "bad CAS2W operand";				return 0;			}			break;		case I32:	/* 32 bit immediate */		case BR32:			ap->eatype = IMM;			if (i32(ip, &ap->immediate) < 0)				return -1;			break;		case IV:	/* immediate data depends on size field */			if (getimm(ip, ap, IV) < 0)				return -1;			break;		case BR8:	/* branch displacement format */			ap->eatype = IMM;			ap->immediate = opcode&0xff;			if (ap->immediate == 0) {				if (i16(ip, &ap->immediate) < 0)					return -1;			} else if (ap->immediate == 0xff) {				if (i32(ip, &ap->immediate) < 0)					return -1;			} else if (ap->immediate & 0x80)				ap->immediate |= ~0xff;			break;		case STACK:	/* Dummy operand type for Return instructions */		default:			break;		}	}	return 1;}static Optable *instruction(Inst *ip){	ushort opcode, op2;	Optable *op;	int class;	ip->n = 0;	if (getword(ip, ip->addr) < 0)		return 0;	opcode = ip->raw[0];	if (get2(mymap, ip->addr+2, &op2) < 0)		op2 = 0;	class = (opcode>>12)&0x0f;	for (op = optables[class]; op && op->format; op++) {		if (op->opcode != (opcode&op->mask0))			continue;		if (op->op2 != (op2&op->mask1))			continue;		if (op->mask1)			ip->raw[ip->n++] = op2;		return op;	}	ip->errmsg = "Invalid opcode";	return 0;}#pragma	varargck	argpos	bprint		2static voidbprint(Inst *i, char *fmt, ...){	va_list arg;	va_start(arg, fmt);	i->curr = vseprint(i->curr, i->end, fmt, arg);	va_end(arg);}static	char	*regname[] ={	"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "A0",	"A1", "A2", "A3", "A4", "A5", "A6", "A7", "PC", "SB"};static voidplocal(Inst *ip, Operand *ap){	int ret;	long offset;	uvlong moved;	Symbol s;	offset = ap->disp;	if (!findsym(ip->addr, CTEXT, &s))		goto none;	moved = pc2sp(ip->addr);	if (moved == -1)		goto none;	if (offset > moved) {		/* above frame - must be argument */		offset -= moved;		ret = getauto(&s, offset-mach->szaddr, CPARAM, &s);	} else				/* below frame - must be automatic */		ret = getauto(&s, moved-offset, CPARAM, &s);	if (ret)		bprint(ip, "%s+%lux", s.name, offset);	elsenone:		bprint(ip, "%lux", ap->disp);}/* *	this guy does all the work of printing the base and index component *	of an EA. */static intpidx(Inst *ip, int ext, int reg, char *bfmt, char *ifmt, char *nobase){	char *s;	int printed;	char buf[512];	printed = 1;	if (ext&0x80) {				/* Base suppressed */		if (reg == 16)			bprint(ip, bfmt, "(ZPC)");		else if (nobase)			bprint(ip, nobase);		else			printed = 0;	} else					/* format base reg */		bprint(ip, bfmt, regname[reg]);	if (ext & 0x40)				/* index suppressed */		return printed;	switch ((ext>>9)&0x03)	{	case 0x01:		s = "*2";		break;	case 0x02:		s = "*4";		break;	case 0x03:		s = "*8";		break;	default:		if (ext&0x80)			s = "*1";		else			s = "";		break;	}	sprint(buf, "%s.%c%s", regname[(ext>>12)&0x0f], (ext&0x800) ? 'L' : 'W', s);	if (!printed)		bprint(ip, ifmt, buf);	else		bprint(ip, "(%s)", buf);	return 1;}static voidprindex(Inst *ip, int reg, Operand *ap){	short ext;	int left;	int disp;	left = ip->end-ip->curr;	if (left <= 0)		return;	ext = ap->ext;	disp = ap->disp;		/* look for static base register references */	if ((ext&0xa0) == 0x20 && reg == 14 && mach->sb && disp) {		reg = 17;		/* "A6" -> "SB" */		disp += mach->sb;	}	if ((ext&0x100) == 0) {		/* brief form */		if (reg == 15)			plocal(ip, ap);		else if (disp)			ip->curr += symoff(ip->curr, left, disp, CANY);		pidx(ip, ext&0xff00, reg, "(%s)", "(%s)", 0);		return;	}	switch(ext&0x3f)	/* bd size, && i/is */	{	case 0x10:		if (!pidx(ip, ext, reg, "(%s)", "(%s)", 0))			bprint(ip, "#0");		break;	case 0x11:		if (pidx(ip, ext, reg, "((%s)", "((%s)", 0))			bprint(ip, ")");		else			bprint(ip, "#0");		break;	case 0x12:	case 0x13:		ip->curr += symoff(ip->curr, left, ap->outer, CANY);		if (pidx(ip, ext, reg, "((%s)", "((%s)", 0))			bprint(ip, ")");		break;	case 0x15:		if (!pidx(ip, ext, reg, "((%s))", "(%s)", 0))			bprint(ip, "#0");		break;	case 0x16:	case 0x17:		ip->curr += symoff(ip->curr, left, ap->outer, CANY);		pidx(ip, ext, reg, "((%s))", "(%s)", 0);		break;	case 0x20:	case 0x30:		if (reg == 15)			plocal(ip, ap);		else			ip->curr += symoff(ip->curr, left, disp, CANY);		pidx(ip, ext, reg, "(%s)", "(%s)", 0);		break;	case 0x21:	case 0x31:		*ip->curr++ = '(';		if (reg == 15)			plocal(ip, ap);		else			ip->curr += symoff(ip->curr, left-1, disp, CANY);		pidx(ip, ext, reg, "(%s)", "(%s)", 0);		bprint(ip, ")");		break;	case 0x22:	case 0x23:	case 0x32:	case 0x33:		ip->curr += symoff(ip->curr, left, ap->outer, CANY);		bprint(ip, "(");		if (reg == 15)			plocal(ip, ap);		else			ip->curr += symoff(ip->curr, ip->end-ip->curr, disp, CANY);		pidx(ip, ext, reg, "(%s)", "(%s)", 0);		bprint(ip, ")");		break;	case 0x25:	case 0x35:		*ip->curr++ = '(';		if (reg == 15)			plocal(ip, ap);		else			ip->curr += symoff(ip->curr, left-1, disp, CANY);		if (!pidx(ip, ext, reg, "(%s))", "(%s)", "())"))			bprint(ip, ")");		break;	case 0x26:	case 0x27:	case 0x36:	case 0x37:		ip->curr += symoff(ip->curr, left, ap->outer, CANY);		bprint(ip, "(");		if (reg == 15)			plocal(ip, ap);		else			ip->curr += symoff(ip->curr, ip->end-ip->curr, disp, CANY);		pidx(ip, ext, reg, "(%s))", "(%s)", "())");		break;	default:		bprint(ip, "??%x??", ext);		ip->errmsg = "bad EA";		break;	}}static	voidpea(int reg, Inst *ip, Operand *ap){	int i, left;	left = ip->end-ip->curr;	if (left < 0)		return;	switch(ap->eatype)	{	case Dreg:		bprint(ip, "R%d", reg);		break;	case Areg:		bprint(ip, "A%d", reg);		break;	case AInd:		bprint(ip, "(A%d)", reg);		break;	case APinc:		bprint(ip, "(A%d)+", reg);		break;	case APdec:		bprint(ip, "-(A%d)", reg);		break;	case PDisp:		ip->curr += symoff(ip->curr, left, ip->addr+2+ap->disp, CANY);		break;	case PXD:		prindex(ip, 16, ap);		break;	case ADisp:	/* references off the static base */		if (reg == 6 && mach->sb && ap->disp) {			ip->curr += symoff(ip->curr, left, ap->disp+mach->sb, CANY);			bprint(ip, "(SB)");			break;		}			/* reference autos and parameters off the stack */		if (reg == 7)			plocal(ip, ap);		else			ip->curr += symoff(ip->curr, left, ap->disp, CANY);		bprint(ip, "(A%d)", reg);		break;	case BXD:		prindex(ip, reg+8, ap);		break;	case ABS:		ip->curr += symoff(ip->curr, left, ap->immediate, CANY);		bprint(ip, "($0)");		break;	case IMM:		*ip->curr++ = '$';		ip->curr += symoff(ip->curr, left-1, ap->immediate, CANY);		break;	case IREAL:		*ip->curr++ = '$';		ip->curr += beieeesftos(ip->curr, left-1, (void*) ap->floater);		break;	case IDBL:		*ip->curr++ = '$';		ip->curr += beieeedftos(ip->curr, left-1, (void*) ap->floater);		break;

⌨️ 快捷键说明

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