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

📄 asm.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include	"l.h"#define	LPUT(c)\	{\		cbp[0] = (c);\		cbp[1] = (c)>>8;\		cbp[2] = (c)>>16;\		cbp[3] = (c)>>24;\		cbp += 4;\		cbc -= 4;\		if(cbc <= 0)\			cflush();\	}#define	CPUT(c)\	{\		cbp[0] = (c);\		cbp++;\		cbc--;\		if(cbc <= 0)\			cflush();\	}#define	VLPUT(c)\	{\		cbp[0] = (c);\		cbp[1] = (c)>>8;\		cbp[2] = (c)>>16;\		cbp[3] = (c)>>24;\		cbp[4] = (c)>>32;\		cbp[5] = (c)>>40;\		cbp[6] = (c)>>48;\		cbp[7] = (c)>>56;\		cbp += 8;\		cbc -= 8;\		if(cbc <= 0)\			cflush();\	}#define	LPUTBE(c)\	{\		cbp[0] = (c)>>24;\		cbp[1] = (c)>>16;\		cbp[2] = (c)>>8;\		cbp[3] = (c);\		cbp += 4;\		cbc -= 4;\		if(cbc <= 0)\			cflush();\	}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 && s->type != SLEAF)		diag("entry not text: %s", s->name);	return s->value;}voidasmb(void){	Prog *p;	vlong t;	Optab *o;	if(debug['v'])		Bprint(&bso, "%5.2f asm\n", cputime());	Bflush(&bso);	seek(cout, HEADR, 0);	pc = INITTEXT;	for(p = firstp; p != P; p = p->link) {		if(p->as == ATEXT) {			curtext = p;			autosize = p->to.offset + 8;		}		if(p->pc != pc) {			diag("phase error %lux sb %lux",				p->pc, pc);			if(!debug['a'])				prasm(curp);			pc = p->pc;		}		if (p->as == AMOVQ || p->as == AMOVT) {			if ((p->from.reg == REGSP) && (p->from.offset&7) != 0			|| (p->to.reg == REGSP) && (p->to.offset&7) != 0)				diag("bad stack alignment: %P", p);			if ((p->from.reg == REGSB) && (p->from.offset&7) != 0			|| (p->to.reg == REGSB) && (p->to.offset&7) != 0)				diag("bad global alignment: %P", p);		}		curp = p;		o = oplook(p);	/* could probably avoid this call */		if(asmout(p, o)) {			p = p->link;			pc += 4;		}		pc += o->size;	}	if(debug['a'])		Bprint(&bso, "\n");	Bflush(&bso);	cflush();	curtext = P;	switch(HEADTYPE) {	case 0:		seek(cout, rnd(HEADR+textsize, 8192), 0);		break;	case 1:	case 2:	case 3:		seek(cout, HEADR+textsize, 0);		break;	}	for(t = 0; t < datsize; t += sizeof(buf)-100) {		if(datsize-t > sizeof(buf)-100)			datblk(t, sizeof(buf)-100);		else			datblk(t, datsize-t);	}	symsize = 0;	lcsize = 0;	if(!debug['s']) {		if(debug['v'])			Bprint(&bso, "%5.2f sym\n", cputime());		Bflush(&bso);		switch(HEADTYPE) {		case 0:			seek(cout, rnd(HEADR+textsize, 8192)+datsize, 0);			break;		case 2:		case 1:		case 3:			seek(cout, HEADR+textsize+datsize, 0);			break;		}		if(!debug['s'])			asmsym();		if(debug['v'])			Bprint(&bso, "%5.2f pc\n", cputime());		Bflush(&bso);		if(!debug['s'])			asmlc();		cflush();	}	if(debug['v'])		Bprint(&bso, "%5.2f header\n", cputime());	Bflush(&bso);	seek(cout, 0L, 0);	switch(HEADTYPE) {	case 0:		lput(0x0183L);		/* magic and sections */		lput(0L);			/* time and date */		vlput(rnd(HEADR+textsize, 8192)+datsize);		lput(symsize);			/* nsyms */		lput(0x50L|(7L<<16));		/* size of optional hdr and flags */		lput(0413|(0x101L<<16));	/* magic and version */		lput(-1);			/* pad for alignment */		vlput(rnd(HEADR+textsize, 8192));		/* sizes */		vlput(datsize);		vlput(bsssize);		vlput(entryvalue());		/* va of entry */		vlput(INITTEXT-HEADR);		/* va of base of text */		vlput(INITDAT);			/* va of base of data */		vlput(INITDAT+datsize);		/* va of base of bss */		lput(~0L);			/* gp reg mask */		/* dubious stuff starts here */		lput(0L);		lput(0L);		lput(0L);		lput(0L);		lput(~0L);			/* gp value ?? */		break;	case 1:		lput(0x0183L);		/* magic and sections */		lput(0L);			/* time and date */		vlput(HEADR+textsize+datsize);		lput(symsize);			/* nsyms */		lput(0x54L|(7L<<16));		/* size of optional hdr and flags */		lput(0407|(0x101L<<16));	/* magic and version */		lput(-1);			/* pad for alignment */		vlput(textsize);		/* sizes */		vlput(datsize);		vlput(bsssize);		vlput(entryvalue());		/* va of entry */		vlput(INITTEXT);		/* va of base of text */		vlput(INITDAT);			/* va of base of data */		vlput(INITDAT+datsize);		/* va of base of bss */		lput(~0L);			/* gp reg mask */		/* dubious stuff starts here */		lput(lcsize);		lput(0L);		lput(0L);		lput(0L);		lput(~0L);			/* gp value ?? */		lput(0L);			/* complete mystery */		break;	case 2:		lputbe(0x84b);			/* magic */		lputbe(textsize);		/* sizes */		lputbe(datsize);		lputbe(bsssize);		lputbe(symsize);		/* nsyms */		lputbe(entryvalue());		/* va of entry */		lputbe(0L);		lputbe(lcsize);		break;	case 3:		/* ``headerless'' boot image -- magic no is a branch */		lput(0xc3e00007);		/* magic (branch) */		lputbe(textsize);		/* sizes */		lputbe(datsize);		lputbe(bsssize);		lputbe(symsize);		/* nsyms */		lputbe(entryvalue());		/* va of entry */		lputbe(0L);		lputbe(lcsize);		break;	}	cflush();}voidlput(long l){	LPUT(l);}voidlputbe(long l){	LPUTBE(l);}voidvlput(vlong l){	VLPUT(l);}voidcflush(void){	int n;	n = sizeof(buf.cbuf) - cbc;	if(n)		write(cout, buf.cbuf, n);	cbp = buf.cbuf;	cbc = sizeof(buf.cbuf);}voidasmsym(void){	Prog *p;	Auto *a;	Sym *s;	int h;	s = lookup("etext", 0);	if(s->type == STEXT)		putsymb(s->name, 'T', s->value, s->version);	for(h=0; h<NHASH; h++)		for(s=hash[h]; s!=S; s=s->link)			switch(s->type) {			case SCONST:				putsymb(s->name, 'D', s->value, s->version);				continue;			case SDATA:				putsymb(s->name, 'D', s->value+INITDAT, s->version);				continue;			case SBSS:				putsymb(s->name, 'B', s->value+INITDAT, s->version);				continue;			case SFILE:				putsymb(s->name, 'f', s->value, s->version);				continue;			}	for(p=textp; p!=P; p=p->cond) {		s = p->from.sym;		if(s->type != STEXT && s->type != SLEAF)			continue;		/* filenames first */		for(a=p->to.autom; a; a=a->link)			if(a->type == D_FILE)				putsymb(a->sym->name, 'z', a->offset, 0);			else			if(a->type == D_FILE1)				putsymb(a->sym->name, 'Z', a->offset, 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+8, 0);		for(a=p->to.autom; a; a=a->link)			if(a->type == D_AUTO)				putsymb(a->sym->name, 'a', -a->offset, 0);			else			if(a->type == D_PARAM)				putsymb(a->sym->name, 'p', a->offset, 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++;	LPUTBE(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){	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;		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]];					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) {				if(p->to.sym->type == STEXT ||				   p->to.sym->type == SLEAF)					d += p->to.sym->value;				if(p->to.sym->type == SDATA)					d += p->to.sym->value + INITDAT;				if(p->to.sym->type == SBSS)					d += p->to.sym->value + INITDAT;			}			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;			case 8:				for(; i<4; i++) {					buf.dbuf[l] = cast[inuxi4[i]];					l++;				}				d = p->to.offset >> 32;				for(; i<c; i++) {					buf.dbuf[l] = cast[inuxi4[i-4]];					l++;				}				break;			}			break;		}	}	write(cout, buf.dbuf, n);}#define	OP_RRR(op,r1,r2,r3)\	(op|(((r1)&31L)<<16)|(((r2)&31L)<<21)|((r3)&31L))#define	OP_IRR(op,i,r2,r3)\	(op|(((i)&255L)<<13)|0x1000|(((r2)&31L)<<21)|((r3)&31L))#define	OP_MEM(op,d,r1,r2)\	(op|(((r1)&31L)<<16)|(((r2)&31L)<<21)|((d)&0xffff))#define OP_BR(op,d,r1)\	(op|((d)&0x1fffff)|(((r1)&31L)<<21))intasmout(Prog *p, Optab *o){	long o1, o2, o3, o4, o5, o6;	vlong v;	int r, a;	o1 = 0;	o2 = 0;	o3 = 0;	o4 = 0;	o5 = 0;	o6 = 0;	switch(o->type) {	default:		diag("unknown type %d", o->type);		if(!debug['a'])			prasm(p);		break;	case 0:		/* pseudo ops */		break;	case 1:		/* register-register moves */		if(p->as == AMOVB || p->as == AMOVW)		/* noop should rewrite */			diag("forbidden SEX: %P", p);		if(p->as == AMOVBU || p->as == AMOVWU) {			v = 1;			if (p->as == AMOVWU)

⌨️ 快捷键说明

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