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

📄 asm.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include	"l.h"short	opa[20];short	*op;longentryvalue(void){	char *a;	Sym *s;	a = INITENTRY;	if(*a >= '0' && *a <= '9')		return atolwhex(a);	s = lookup(a, 0);	if(s->type == 0)		return INITTEXT;	if(s->type != STEXT)		diag("entry not text: %s", s->name);	return s->value;}voidasmb(void){	Prog *p;	long v;	int a;	short *op1;	if(debug['v'])		Bprint(&bso, "%5.2f asmb\n", cputime());	Bflush(&bso);	seek(cout, HEADR, 0);	pc = INITTEXT;	curp = firstp;	for(p = firstp; p != P; p = p->link) {		if(p->as == ATEXT)			curtext = p;		if(p->pc != pc) {			if(!debug['a'])				print("%P\n", curp);			diag("phase error %lux sb %lux in %s", p->pc, pc, TNAME);			pc = p->pc;		}		curp = p;		if(debug['a'])			Bprint(&bso, "%lux:%P\n", pc, curp);		asmins(p);		if(cbc < sizeof(opa))			cflush();		for(op1 = opa; op1 < op; op1++) {			a = *op1;			*cbp++ = a >> 8;			*cbp++ = a;		}		a = 2*(op - opa);		pc += a;		cbc -= a;		if(debug['a']) {			for(op1 = opa; op1 < op; op1++)				if(op1 == opa)					Bprint(&bso, "\t\t%4ux", *op1 & 0xffff);				else					Bprint(&bso, " %4ux", *op1 & 0xffff);			if(op != opa)				Bprint(&bso, "\n");		}	}	cflush();	switch(HEADTYPE) {	case 0:	/* this is garbage */		seek(cout, rnd(HEADR+textsize, 8192), 0);		break;	case 1:	/* plan9 boot data goes into text */		seek(cout, rnd(HEADR+textsize, INITRND), 0);		break;	case 2:	/* plan 9 */		seek(cout, HEADR+textsize, 0);		break;	case 3:	/* next boot */		seek(cout, HEADR+rnd(textsize, INITRND), 0);		break;	case 4:	/* preprocess pilot */		seek(cout, HEADR+textsize, 0);		break;	}	if(debug['v'])		Bprint(&bso, "%5.2f datblk\n", cputime());	Bflush(&bso);	for(v = 0; v < datsize; v += sizeof(buf)-100) {		if(datsize-v > sizeof(buf)-100)			datblk(v, sizeof(buf)-100);		else			datblk(v, datsize-v);	}	symsize = 0;	spsize = 0;	lcsize = 0;	Bflush(&bso);	switch(HEADTYPE) {	default:		seek(cout, rnd(HEADR+textsize, 8192)+datsize, 0);		break;	case 1:	/* plan9 boot data goes into text */		seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0);		break;	case 2:	/* plan 9 */		seek(cout, HEADR+textsize+datsize, 0);		break;	case 3:	/* next boot */		seek(cout, HEADR+rnd(textsize, INITRND)+datsize, 0);		break;	}	if(!debug['s']) {		if(debug['v'])			Bprint(&bso, "%5.2f sym\n", cputime());		asmsym();	}	Bflush(&bso);	if(!debug['s']) {		if(debug['v'])			Bprint(&bso, "%5.2f sp\n", cputime());		asmsp();	}	Bflush(&bso);	if(!debug['s']) {		if(debug['v'])			Bprint(&bso, "%5.2f pc\n", cputime());		asmlc();	}	cflush();	if(debug['v'])		Bprint(&bso, "%5.2f headr\n", cputime());	Bflush(&bso);	seek(cout, 0L, 0);	switch(HEADTYPE) {	default:		lput(0x160L<<16);		/* magic and sections */		lput(0L);			/* time and date */		lput(rnd(HEADR+textsize, 4096)+datsize);		lput(symsize);			/* nsyms */		lput((0x38L<<16)|7L);		/* size of optional hdr and flags */		lput((0413<<16)|0437L);		/* magic and version */		lput(rnd(HEADR+textsize, 4096));	/* sizes */		lput(datsize);		lput(bsssize);		lput(entryvalue());		/* va of entry */		lput(INITTEXT-HEADR);		/* va of base of text */		lput(INITDAT);			/* va of base of data */		lput(INITDAT+datsize);		/* va of base of bss */		lput(~0L);			/* gp reg mask */		lput(0L);		lput(0L);		lput(0L);		lput(0L);		lput(~0L);			/* gp value ?? */		break;	case 1:	/* plan9 boot data goes into text */		lput(0407);			/* magic */		lput(rnd(HEADR+textsize, INITRND)-HEADR+datsize);		/* sizes */		lput(0);		lput(bsssize);		lput(symsize);			/* nsyms */		lput(entryvalue());		/* va of entry */		lput(spsize);			/* sp offsets */		lput(lcsize);			/* line offsets */		break;	case 2:	/* plan 9 */		lput(0407);			/* magic */		lput(textsize);			/* sizes */		lput(datsize);		lput(bsssize);		lput(symsize);			/* nsyms */		lput(entryvalue());		/* va of entry */		lput(spsize);			/* sp offsets */		lput(lcsize);			/* line offsets */		break;	case 3:	/* next boot */		/* header */		lput(0xfeedfaceL);			/* magic */		lput(6);				/* 68040 */		lput(1);				/* more 68040 */		lput(5);				/* file type 'boot' */		lput(HEADTYPE);				/* number commands */		lput(HEADR-7*4);			/* sizeof commands */		lput(1);				/* no undefineds */		/* command 1 text */		lput(1);				/* command = 'segment' */		lput(124);				/* command size */		s16put("__TEXT");			/* botch?? entryvalue() */		lput(INITTEXT);				/* va of start */		lput(rnd(textsize, 8192));		/* va size */		lput(HEADR);				/* file offset */		lput(rnd(textsize, 8192));		/* file size */		lput(7);				/* max prot */		lput(7);				/* init prot */		lput(1);				/* number of sections */		lput(0);				/* flags */		/* text section */		s16put("__text");		s16put("__TEXT");			/* botch?? entryvalue() */		lput(INITTEXT);				/* va of start */		lput(textsize);				/* va size */		lput(HEADR);				/* file offset */		lput(2);				/* align */		lput(0);				/* reloff */		lput(0);				/* nreloc */		lput(0);				/* flags */		lput(0);				/* reserved1 */		lput(0);				/* reserved2 */		/* command 1 data */		lput(1);				/* command = 'segment' */		lput(192);				/* command size */		s16put("__DATA");		lput(INITDAT);				/* va of start */		lput(rnd(datsize, 8192));		/* va size */		lput(HEADR+rnd(textsize, 8192));	/* file offset */		lput(rnd(datsize, 8192));		/* file size */		lput(7);				/* max prot */		lput(7);				/* init prot */		lput(2);				/* number of sections */		lput(0);				/* flags */		/* data section */		s16put("__data");		s16put("__DATA");		lput(INITDAT);				/* va of start */		lput(datsize);				/* va size */		lput(HEADR+rnd(textsize, 8192));	/* file offset */		lput(2);				/* align */		lput(0);				/* reloff */		lput(0);				/* nreloc */		lput(0);				/* flags */		lput(0);				/* reserved1 */		lput(0);				/* reserved2 */		/* bss section */		s16put("__bss");		s16put("__DATA");		lput(INITDAT+datsize);			/* va of start */		lput(bsssize);				/* va size */		lput(0);				/* file offset */		lput(2);				/* align */		lput(0);				/* reloff */		lput(0);				/* nreloc */		lput(1);				/* flags = zero fill */		lput(0);				/* reserved1 */		lput(0);				/* reserved2 */		/* command 2 symbol */		lput(2);				/* command = 'symbol' */		lput(24);				/* command size */		lput(HEADR+rnd(textsize, INITRND)			+datsize);			/* symoff */		lput(symsize);				/* nsyms */		lput(spsize);				/* sp offsets */		lput(lcsize);				/* line offsets */		break;	}	cflush();}voidasmins(Prog *p){	Optab *o;	int t, a, b;	long v;	Prog *q;	op = opa + 1;	if(special[p->from.type])	switch(p->from.type) {	case D_CCR:		if(p->as != AMOVW)			goto bad;		a = asmea(p, &p->to);		if((a & 0170) == 010)			goto bad;		opa[0] = 0x42c0 | a;		/* mov from ccr */		return;	case D_SR:		if(p->as != AMOVW)			goto bad;		a = asmea(p, &p->to);		if((a & 0170) == 010)			goto bad;		opa[0] = 0x40c0 | a;		/* mov from sr */		return;	case D_USP:		if(p->as != AMOVL)			goto bad;		a = asmea(p, &p->to);		if((a & 0170) == 010) {			opa[0] = 0x4e68|(a&7);	/* mov usp An */			return;		}		t = 0x800;		goto movec1;	case D_SFC:		t = 0x000;		goto movec1;	case D_DFC:		t = 0x001;		goto movec1;	case D_CACR:		t = 0x002;		goto movec1;	case D_TC:		t = 0x003;		goto movec1;	case D_ITT0:		t = 0x004;		goto movec1;	case D_ITT1:		t = 0x005;		goto movec1;	case D_DTT0:		t = 0x006;		goto movec1;	case D_DTT1:		t = 0x007;		goto movec1;	case D_VBR:		t = 0x801;		goto movec1;	case D_CAAR:		t = 0x802;		goto movec1;	case D_MSP:		t = 0x803;		goto movec1;	case D_ISP:		t = 0x804;		goto movec1;	case D_MMUSR:		t = 0x805;		goto movec1;	case D_URP:		t = 0x806;		goto movec1;	case D_SRP:		t = 0x807;		goto movec1;	movec1:		if(p->as != AMOVL)			goto bad;		opa[0] = 0x4e7a;			/* mov spc Dn */		a = asmea(p, &p->to);		b = a & 0170;		if(b == 0 || b == 010) {			*op++ = (a<<12) | t;			return;		}		goto bad;	case D_FPCR:		t = 0xb000;		goto movec3;	case D_FPSR:		t = 0xa800;		goto movec3;	case D_FPIAR:		t = 0xa400;	movec3:		if(p->as != AMOVL)			goto bad;		op++;		a = asmea(p, &p->to);		opa[0] = optab[AFMOVEL].opcode0 | a;		opa[1] = t;		return;	}	if(special[p->to.type])	switch(p->to.type) {	case D_CCR:		if(p->as != AMOVW)		/* botch, needs and, eor etc. */			goto bad;		a = asmea(p, &p->from);		if((a & 0170) == 010)			goto bad;		opa[0] = 0x44c0 | a;		/* mov to ccr */		return;	case D_SR:		if(p->as != AMOVW)		/* botch, needs and, eor etc. */			goto bad;		a = asmea(p, &p->from);		if((a & 0170) == 010)			goto bad;		opa[0] = 0x46c0 | a;		/* mov to sr */		return;	case D_USP:		if(p->as != AMOVL)			goto bad;		a = asmea(p, &p->from);		if((a & 0170) == 010) {			opa[0] = 0x4e60|(a&7);	/* mov An usp */			return;		}		t = 0x800;		goto movec2;	case D_SFC:		t = 0x000;		goto movec2;	case D_DFC:		t = 0x001;		goto movec2;	case D_CACR:		t = 0x002;		goto movec2;	case D_TC:		t = 0x003;		goto movec2;	case D_ITT0:		t = 0x004;		goto movec2;	case D_ITT1:		t = 0x005;		goto movec2;	case D_DTT0:		t = 0x006;		goto movec2;	case D_DTT1:		t = 0x007;		goto movec2;	case D_VBR:		t = 0x801;		goto movec2;	case D_CAAR:		t = 0x802;		goto movec2;	case D_MSP:		t = 0x803;		goto movec2;	case D_ISP:		t = 0x804;		goto movec2;	case D_MMUSR:		t = 0x805;		goto movec2;	case D_URP:		t = 0x806;		goto movec2;	case D_SRP:		t = 0x807;		goto movec2;	movec2:		if(p->as != AMOVL)			goto bad;		opa[0] = 0x4e7b;			/* mov Dn spc */		a = asmea(p, &p->from);		b = a & 0170;		if(b == 0 || b == 010) {			*op++ = (a<<12) | t;			return;		}		goto bad;	case D_FPCR:		t = 0x9000;		goto movec4;	case D_FPSR:		t = 0x8800;		goto movec4;	case D_FPIAR:		t = 0x8400;	movec4:		if(p->as != AMOVL)			goto bad;		op++;		a = asmea(p, &p->from);		opa[0] = optab[AFMOVEL].opcode0 | a;		opa[1] = t;		return;	}	o = &optab[p->as];	t = o->opcode0;	switch(o->optype) {	case 0:		/* pseudo ops */		if(p->as != ATEXT && p->as != ANOP) {			if(!debug['a'])				print("%P\n", p);			diag("unimplemented instruction in %s", TNAME);			return;		}		op = opa;		return;	case 1:		/* branches */		if(p->to.type != D_BRANCH)			goto bad;		a = asmea(p, &p->to);		/* hack to turn 3-word bsr into 2-word jsr */		if(a == 0xff && p->as == ABSR &&		   p->pcond->pc < 32768L && p->pcond->pc >= 0) {			op = opa + 1;			t = o->opcode1;			*op++ = p->pcond->pc;			break;		}		t |= a;		break;	case 2:		/* move */		a = asmea(p, &p->from);		b = asmea(p, &p->to);		if((a & 0170) == 0110) { /* src quick */			t = o->opcode1;			if((b & 0170) != 0)				goto bad;			t |= a >> 7;			t |= b << 9;			break;		}		t |= a;		t |= (b&7) << 9;		t |= (b&070) << 3;		break;	case 3:		/* add */		a = asmea(p, &p->from);		b = asmea(p, &p->to);		if((a & 0170) == 0110) { /* src quick */			t = o->opcode1;			t |= (a&01600) << 2;			t |= b;			break;		}		if((b & 0170) == 0) { /* dst Dn */			t |= a;			t |= (b & 7) << 9;			break;		}		if((b & 0170) == 010) { /* dst An */			if((t & 0xc0) == 0)				goto bad;			t = o->opcode2;			t |= a;									t |= (b & 7) << 9;			break;		}		if((a & 0170) == 0) { /* src Dn */			t |= 0x100;			t |= (a & 7) << 9;			t |= b;			break;		}		if((a & 0177) == 074) { /* src immed */			t = o->opcode3;			t |= b;			break;		}		goto bad;	case 4:		/* no operands */		break;	case 5:		/* tst */		t |= asmea(p, &p->to);		if((t&0170) == 010)			goto bad;		break;	case 6:		/* lea */		a = asmea(p, &p->from);		b = asmea(p, &p->to);		if((b & 0170) != 010)			goto bad;		t |= a;		t |= (b & 7) << 9;		break;	case 7:		/* cmp */		b = asmea(p, &p->to);		a = asmea(p, &p->from);		if((a & 0170) == 010) {	/* dst An */			t = o->opcode1;			if(t == 0)	/* cmpb illegal */				goto bad;			t |= 0xc0;			t |= b;									t |= (a & 7) << 9;			break;		}		if((b & 0177) == 074) { /* src immed */			t = o->opcode2;			t |= a;			break;		}		if((a & 0170) == 0) {	/* dst Dn */			t |= b;			t |= (a&7) << 9;			break;		}		if((b&0170) == 030 && (a&0170) == 030) { /* (A)+,(A)+ */			t = o->opcode3;			t |= b & 7;			t |= (a & 7) << 9;			break;		}		goto bad;	case 8:		/* svc */		*op++ = optab[ARTS].opcode0;		break;	case 9:		/* and */		a = asmea(p, &p->from);		b = asmea(p, &p->to);		if((a & 0170) == 010)			goto bad;		if((b & 0170) == 0) { /* dst Dn */			t |= a;			t |= (b&7) << 9;			break;		}		if((a & 0170) == 0) { /* src Dn */			t = o->opcode1;			t |= b;			t |= (a&7) << 9;			break;		}		if((a & 0177) == 074) { /* src immed */			t = o->opcode2;			t |= b;			break;		}		goto bad;	case 10:	/* eor */		a = asmea(p, &p->from);		b = asmea(p, &p->to);		if((a & 0170) == 010)			goto bad;		if((a & 0170) == 0) { /* src Dn */			t |= b;			t |= (a&7) << 9;			break;		}		if((a & 0177) == 074) { /* src immed */			t = o->opcode1;			t |= b;			break;		}		goto bad;	case 11:	/* ext */		b = asmea(p, &p->to);		if((b & 0170) == 0) { /* dst Dn */			t |= b;			break;		}		goto bad;	case 12:	/* shift */		a = asmea(p, &p->from);		b = asmea(p, &p->to);		if((b & 0170) == 0) { /* dst Dn */			if((a & 0177) == 0110) { /* src quick */				t |= (a & 01600) << 2;				t |= b;				break;			}			if((a & 0170) == 0) { /* src Dn */				t |= 0x20;				t |= a << 9;				t |= b;				break;			}			goto bad;		}		goto bad;	case 13:	/* mul, div short */		a = asmea(p, &p->from);		b = asmea(p, &p->to);		if((b & 0170) == 0) { /* dst Dn */			if((a & 0170) == 010)				goto bad;				t |= a;			t |= b << 9;			break;		}		goto bad;	case 14:	/* mul, div long */		*op++ = o->opcode1;		a = asmea(p, &p->from);		b = asmea(p, &p->to);		if((b & 0170) == 0) { /* dst Dn */			if((a & 0170) == 010)				goto bad;				t |= a;			opa[1] |= b << 12;			opa[1] |= b+1;			break;		}		goto bad;	case 15:	/* dec and branch */		if(p->to.type != D_BRANCH)			goto bad;		v = p->pcond->pc - p->pc - 2;		if(v < -32768L || v >= 32768L)			goto bad;		*op++ = v;		a = asmea(p, &p->from);		if((a & 0170) != 0)			goto bad;		t |= a;		break;	case 16:	/* fmove */		*op++ = o->opcode1;		a = asmea(p, &p->from);		b = asmea(p, &p->to);		if((a & 0170) == 0100) { /* src Fn */			if((b & 0170) == 0100) { /* both Fn */				opa[1] |= (a&7) << 10;				opa[1] |= (b&7) << 7;				break;			}			t |= b;			opa[1] = o->opcode2;			opa[1] |= (a&7) << 7;			break;		}		if((b & 0170) != 0100) /* dst Fn */			goto bad;		t |= a;		opa[1] = o->opcode3;		opa[1] |= (b&7) << 7;		break;

⌨️ 快捷键说明

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