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

📄 asm.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
		/* filenames first */		for(a=p->to.autom; a; a=a->link)			if(a->type == D_FILE)				putsymb(a->asym->name, 'z', a->aoffset, 0);			else			if(a->type == D_FILE1)				putsymb(a->asym->name, 'Z', a->aoffset, 0);		if(s->type == STEXT)			putsymb(s->name, 'T', s->value, s->version);		else			putsymb(s->name, 'L', s->value, s->version);		/* frame, auto and param after */		putsymb(".frame", 'm', p->to.offset+4, 0);		for(a=p->to.autom; a; a=a->link)			if(a->type == D_AUTO)				putsymb(a->asym->name, 'a', -a->aoffset, 0);			else			if(a->type == D_PARAM)				putsymb(a->asym->name, 'p', a->aoffset, 0);	}	if(debug['v'] || debug['n'])		Bprint(&bso, "symsize = %lud\n", symsize);	Bflush(&bso);}voidputsymb(char *s, int t, long v, int ver){	int i, f;	if(t == 'f')		s++;	LBEPUT(v);	if(ver)		t += 'a' - 'A';	CPUT(t+0x80);			/* 0x80 is variable length */	if(t == 'Z' || t == 'z') {		CPUT(s[0]);		for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {			CPUT(s[i]);			CPUT(s[i+1]);		}		CPUT(0);		CPUT(0);		i++;	}	else {		for(i=0; s[i]; i++)			CPUT(s[i]);		CPUT(0);	}	symsize += 4 + 1 + i + 1;	if(debug['n']) {		if(t == 'z' || t == 'Z') {			Bprint(&bso, "%c %.8lux ", t, v);			for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) {				f = ((s[i]&0xff) << 8) | (s[i+1]&0xff);				Bprint(&bso, "/%x", f);			}			Bprint(&bso, "\n");			return;		}		if(ver)			Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver);		else			Bprint(&bso, "%c %.8lux %s\n", t, v, s);	}}#define	MINLC	4voidasmlc(void){	long oldpc, oldlc;	Prog *p;	long v, s;	oldpc = INITTEXT;	oldlc = 0;	for(p = firstp; p != P; p = p->link) {		if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {			if(p->as == ATEXT)				curtext = p;			if(debug['L'])				Bprint(&bso, "%6lux %P\n",					p->pc, p);			continue;		}		if(debug['L'])			Bprint(&bso, "\t\t%6ld", lcsize);		v = (p->pc - oldpc) / MINLC;		while(v) {			s = 127;			if(v < 127)				s = v;			CPUT(s+128);	/* 129-255 +pc */			if(debug['L'])				Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);			v -= s;			lcsize++;		}		s = p->line - oldlc;		oldlc = p->line;		oldpc = p->pc + MINLC;		if(s > 64 || s < -64) {			CPUT(0);	/* 0 vv +lc */			CPUT(s>>24);			CPUT(s>>16);			CPUT(s>>8);			CPUT(s);			if(debug['L']) {				if(s > 0)					Bprint(&bso, " lc+%ld(%d,%ld)\n",						s, 0, s);				else					Bprint(&bso, " lc%ld(%d,%ld)\n",						s, 0, s);				Bprint(&bso, "%6lux %P\n",					p->pc, p);			}			lcsize += 5;			continue;		}		if(s > 0) {			CPUT(0+s);	/* 1-64 +lc */			if(debug['L']) {				Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);				Bprint(&bso, "%6lux %P\n",					p->pc, p);			}		} else {			CPUT(64-s);	/* 65-128 -lc */			if(debug['L']) {				Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);				Bprint(&bso, "%6lux %P\n",					p->pc, p);			}		}		lcsize++;	}	while(lcsize & 1) {		s = 129;		CPUT(s);		lcsize++;	}	if(debug['v'] || debug['L'])		Bprint(&bso, "lcsize = %ld\n", lcsize);	Bflush(&bso);}voiddatblk(long s, long n, int str){	Prog *p;	char *cast;	long l, fl, j, d;	int i, c;	memset(buf.dbuf, 0, n+100);	for(p = datap; p != P; p = p->link) {		curp = p;		if(str != (p->from.sym->type == SSTRING))			continue;		l = p->from.sym->value + p->from.offset - s;		c = p->reg;		i = 0;		if(l < 0) {			if(l+c <= 0)				continue;			while(l < 0) {				l++;				i++;			}		}		if(l >= n)			continue;		if(p->as != AINIT && p->as != ADYNT) {			for(j=l+(c-i)-1; j>=l; j--)				if(buf.dbuf[j]) {					print("%P\n", p);					diag("multiple initialization");					break;				}		}		switch(p->to.type) {		default:			diag("unknown mode in initialization\n%P", p);			break;		case D_FCONST:			switch(c) {			default:			case 4:				fl = ieeedtof(p->to.ieee);				cast = (char*)&fl;				for(; i<c; i++) {					buf.dbuf[l] = cast[fnuxi8[i+4]];					l++;				}				break;			case 8:				cast = (char*)p->to.ieee;				for(; i<c; i++) {					buf.dbuf[l] = cast[fnuxi8[i]];					l++;				}				break;			}			break;		case D_SCONST:			for(; i<c; i++) {				buf.dbuf[l] = p->to.sval[i];				l++;			}			break;		case D_CONST:			d = p->to.offset;			if(p->to.sym) {				switch(p->to.sym->type) {				case STEXT:				case SLEAF:				case SSTRING:					d += p->to.sym->value;					break;				case SDATA:				case SBSS:					d += p->to.sym->value + INITDAT;					break;				}			}			cast = (char*)&d;			switch(c) {			default:				diag("bad nuxi %d %d\n%P", c, i, curp);				break;			case 1:				for(; i<c; i++) {					buf.dbuf[l] = cast[inuxi1[i]];					l++;				}				break;			case 2:				for(; i<c; i++) {					buf.dbuf[l] = cast[inuxi2[i]];					l++;				}				break;			case 4:				for(; i<c; i++) {					buf.dbuf[l] = cast[inuxi4[i]];					l++;				}				break;			}			break;		}	}	write(cout, buf.dbuf, n);}#define	OP_RRR(op,r1,r2,r3)\	(op|(((r1)&31L)<<16)|(((r2)&31L)<<21)|(((r3)&31L)<<11))#define	OP_IRR(op,i,r2,r3)\	(op|((i)&0xffffL)|(((r2)&31L)<<21)|(((r3)&31L)<<16))#define	OP_SRR(op,s,r2,r3)\	(op|(((s)&31L)<<6)|(((r2)&31L)<<16)|(((r3)&31L)<<11))#define	OP_FRRR(op,r1,r2,r3)\	(op|(((r1)&31L)<<16)|(((r2)&31L)<<11)|(((r3)&31L)<<6))#define	OP_JMP(op,i)\		((op)|((i)&0x3ffffffL))#define	OP(x,y)\	(((x)<<3)|((y)<<0))#define	SP(x,y)\	(((x)<<29)|((y)<<26))#define	BCOND(x,y)\	(((x)<<19)|((y)<<16))#define	MMU(x,y)\	(SP(2,0)|(16<<21)|((x)<<3)|((y)<<0))#define	FPF(x,y)\	(SP(2,1)|(16<<21)|((x)<<3)|((y)<<0))#define	FPD(x,y)\	(SP(2,1)|(17<<21)|((x)<<3)|((y)<<0))#define	FPW(x,y)\	(SP(2,1)|(20<<21)|((x)<<3)|((y)<<0))int vshift(int);intasmout(Prog *p, Optab *o, int aflag){	long o1, o2, o3, o4, o5, o6, o7, v;	Prog *ct;	int r, a;	o1 = 0;	o2 = 0;	o3 = 0;	o4 = 0;	o5 = 0;	o6 = 0;	o7 = 0;	switch(o->type) {	default:		diag("unknown type %d", o->type);		if(!debug['a'])			prasm(p);		break;	case 0:		/* pseudo ops */		if(aflag) {			if(p->link) {				if(p->as == ATEXT) {					ct = curtext;					o2 = autosize;					curtext = p;					autosize = p->to.offset + 4;					o1 = asmout(p->link, oplook(p->link), aflag);					curtext = ct;					autosize = o2;				} else					o1 = asmout(p->link, oplook(p->link), aflag);			}			return o1;		}		break;	case 1:		/* mov[v] r1,r2 ==> OR r1,r0,r2 */		o1 = OP_RRR(oprrr(AOR), p->from.reg, REGZERO, p->to.reg);		break;	case 2:		/* add/sub r1,[r2],r3 */		r = p->reg;		if(r == NREG)			r = p->to.reg;		o1 = OP_RRR(oprrr(p->as), p->from.reg, r, p->to.reg);		break;	case 3:		/* mov $soreg, r ==> or/add $i,o,r */		v = regoff(&p->from);		r = p->from.reg;		if(r == NREG)			r = o->param;		a = AADDU;		if(o->a1 == C_ANDCON)			a = AOR;		o1 = OP_IRR(opirr(a), v, r, p->to.reg);		break;	case 4:		/* add $scon,[r1],r2 */		v = regoff(&p->from);		r = p->reg;		if(r == NREG)			r = p->to.reg;		o1 = OP_IRR(opirr(p->as), v, r, p->to.reg);		break;	case 5:		/* syscall */		if(aflag)			return 0;		o1 = oprrr(p->as);		break;	case 6:		/* beq r1,[r2],sbra */		if(aflag)			return 0;		if(p->cond == P)			v = -4 >> 2;		else			v = (p->cond->pc - pc-4) >> 2;		if(((v << 16) >> 16) != v)			diag("short branch too far: %d\n%P", v, p);		o1 = OP_IRR(opirr(p->as), v, p->from.reg, p->reg);		break;	case 7:		/* mov r, soreg ==> sw o(r) */		r = p->to.reg;		if(r == NREG)			r = o->param;		v = regoff(&p->to);		o1 = OP_IRR(opirr(p->as), v, r, p->from.reg);		break;	case 8:		/* mov soreg, r ==> lw o(r) */		r = p->from.reg;		if(r == NREG)			r = o->param;		v = regoff(&p->from);		o1 = OP_IRR(opirr(p->as+ALAST), v, r, p->to.reg);		break;	case 9:		/* asl r1,[r2],r3 */		r = p->reg;		if(r == NREG)			r = p->to.reg;		o1 = OP_RRR(oprrr(p->as), r, p->from.reg, p->to.reg);		break;	case 10:	/* add $con,[r1],r2 ==> mov $con,t; add t,[r1],r2 */		v = regoff(&p->from);		r = AOR;		if(v < 0)			r = AADDU;		o1 = OP_IRR(opirr(r), v, 0, REGTMP);		r = p->reg;		if(r == NREG)			r = p->to.reg;		o2 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg);		break;	case 11:	/* jmp lbra */		if(aflag)			return 0;		if(p->cond == P)			v = p->pc >> 2;		else			v = p->cond->pc >> 2;		o1 = OP_JMP(opirr(p->as), v);		if(!debug['Y'] && p->link && p->cond && isnop(p->link)) {			nop.branch.count--;			nop.branch.outof--;			nop.jump.outof++;			o2 = asmout(p->cond, oplook(p->cond), 1);			if(o2) {				o1 += 1;				if(debug['a'])					Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n",						p->pc, o1, o2, p);				LPUT(o1);				LPUT(o2);				return 1;			}		}		break;	case 12:	/* movbs r,r */		v = 16;		if(p->as == AMOVB)			v = 24;		o1 = OP_SRR(opirr(ASLL), v, p->from.reg, p->to.reg);		o2 = OP_SRR(opirr(ASRA), v, p->to.reg, p->to.reg);		break;	case 13:	/* movbu r,r */		if(p->as == AMOVBU)			o1 = OP_IRR(opirr(AAND), 0xffL, p->from.reg, p->to.reg);		else			o1 = OP_IRR(opirr(AAND), 0xffffL, p->from.reg, p->to.reg);		break;	case 16:	/* sll $c,[r1],r2 */		v = regoff(&p->from);		r = p->reg;		if(r == NREG)			r = p->to.reg;		/* OP_SRR will use only the low 5 bits of the shift value */		if(v >= 32 && vshift(p->as))			o1 = OP_SRR(opirr(p->as+ALAST), v-32, r, p->to.reg);		else 			o1 = OP_SRR(opirr(p->as), v, r, p->to.reg);		break;	case 18:	/* jmp [r1],0(r2) */		if(aflag)			return 0;		r = p->reg;		if(r == NREG)			r = o->param;		o1 = OP_RRR(oprrr(p->as), 0, p->to.reg, r);		break;	case 19:	/* mov $lcon,r ==> lu+or */

⌨️ 快捷键说明

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