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

📄 asm.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include	"l.h"#define	Dbufslop	100#define PADDR(a)	((ulong)(a) & ~0xF0000000)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;	switch(s->type) {	case STEXT:		break;	case SDATA:		if(dlm)			return s->value+INITDAT;	default:		diag("entry not text: %s", s->name);	}	return s->value;}voidwputl(ushort w){	cput(w);	cput(w>>8);}voidwput(ushort w){	cput(w>>8);	cput(w);}voidlput(long l){	cput(l>>24);	cput(l>>16);	cput(l>>8);	cput(l);}voidlputl(long l){	cput(l);	cput(l>>8);	cput(l>>16);	cput(l>>24);}voidstrnput(char *s, int n){	for(; *s && n > 0; s++){		cput(*s);		n--;	}	while(n > 0){		cput(0);		n--;	}}voidasmb(void){	Prog *p;	long v, magic;	int a;	uchar *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;		asmins(p);		if(cbc < sizeof(and))			cflush();		a = (andptr - and);		if(debug['a']) {			Bprint(&bso, pcstr, pc);			for(op1 = and; op1 < andptr; op1++)				Bprint(&bso, "%.2ux", *op1 & 0xff);			Bprint(&bso, "\t%P\n", curp);		}		if(dlm) {			if(p->as == ATEXT)				reloca = nil;			else if(reloca != nil)				diag("reloc failure: %P", curp);		}		memmove(cbp, and, a);		cbp += a;		pc += a;		cbc -= a;	}	cflush();	switch(HEADTYPE) {	default:		diag("unknown header type %d", HEADTYPE);	case 0:		seek(cout, rnd(HEADR+textsize, 8192), 0);		break;	case 1:		textsize = rnd(HEADR+textsize, 4096)-HEADR;		seek(cout, textsize+HEADR, 0);		break;	case 2:	case 5:		seek(cout, HEADR+textsize, 0);		break;	case 3:	case 4:		seek(cout, HEADR+rnd(textsize, INITRND), 0);		break;	}	if(debug['v'])		Bprint(&bso, "%5.2f datblk\n", cputime());	Bflush(&bso);	if(dlm){		char buf[8];		write(cout, buf, INITDAT-textsize);		textsize = INITDAT;	}	for(v = 0; v < datsize; v += sizeof(buf)-Dbufslop) {		if(datsize-v > sizeof(buf)-Dbufslop)			datblk(v, sizeof(buf)-Dbufslop);		else			datblk(v, datsize-v);	}	symsize = 0;	spsize = 0;	lcsize = 0;	if(!debug['s']) {		if(debug['v'])			Bprint(&bso, "%5.2f sym\n", cputime());		Bflush(&bso);		switch(HEADTYPE) {		default:		case 0:			seek(cout, rnd(HEADR+textsize, 8192)+datsize, 0);			break;		case 1:			seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0);			break;		case 2:		case 5:			seek(cout, HEADR+textsize+datsize, 0);			break;		case 3:		case 4:			debug['s'] = 1;			break;		}		if(!debug['s'])			asmsym();		if(debug['v'])			Bprint(&bso, "%5.2f sp\n", cputime());		Bflush(&bso);		if(debug['v'])			Bprint(&bso, "%5.2f pc\n", cputime());		Bflush(&bso);		if(!debug['s'])			asmlc();		if(dlm)			asmdyn();		cflush();	}	else if(dlm){		seek(cout, HEADR+textsize+datsize, 0);		asmdyn();		cflush();	}	if(debug['v'])		Bprint(&bso, "%5.2f headr\n", cputime());	Bflush(&bso);	seek(cout, 0L, 0);	switch(HEADTYPE) {	default:	case 0:	/* garbage */		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:	/* unix coff */		/*		 * file header		 */		lputl(0x0004014c);		/* 4 sections, magic */		lputl(0);			/* unix time stamp */		lputl(0);			/* symbol table */		lputl(0);			/* nsyms */		lputl(0x0003001c);		/* flags, sizeof a.out header */		/*		 * a.out header		 */		lputl(0x10b);			/* magic, version stamp */		lputl(rnd(textsize, INITRND));	/* text sizes */		lputl(datsize);			/* data sizes */		lputl(bsssize);			/* bss sizes */		lput(entryvalue());		/* va of entry */		lputl(INITTEXT);		/* text start */		lputl(INITDAT);			/* data start */		/*		 * text section header		 */		strnput(".text", 8);		lputl(HEADR);			/* pa */		lputl(HEADR);			/* va */		lputl(textsize);		/* text size */		lputl(HEADR);			/* file offset */		lputl(0);			/* relocation */		lputl(0);			/* line numbers */		lputl(0);			/* relocation, line numbers */		lputl(0x20);			/* flags text only */		/*		 * data section header		 */		strnput(".data", 8);		lputl(INITDAT);			/* pa */		lputl(INITDAT);			/* va */		lputl(datsize);			/* data size */		lputl(HEADR+textsize);		/* file offset */		lputl(0);			/* relocation */		lputl(0);			/* line numbers */		lputl(0);			/* relocation, line numbers */		lputl(0x40);			/* flags data only */		/*		 * bss section header		 */		strnput(".bss", 8);		lputl(INITDAT+datsize);		/* pa */		lputl(INITDAT+datsize);		/* va */		lputl(bsssize);			/* bss size */		lputl(0);			/* file offset */		lputl(0);			/* relocation */		lputl(0);			/* line numbers */		lputl(0);			/* relocation, line numbers */		lputl(0x80);			/* flags bss only */		/*		 * comment section header		 */		strnput(".comment", 8);		lputl(0);			/* pa */		lputl(0);			/* va */		lputl(symsize+lcsize);		/* comment size */		lputl(HEADR+textsize+datsize);	/* file offset */		lputl(HEADR+textsize+datsize);	/* offset of syms */		lputl(HEADR+textsize+datsize+symsize);/* offset of line numbers */		lputl(0);			/* relocation, line numbers */		lputl(0x200);			/* flags comment only */		break;	case 2:	/* plan9 */		magic = 4*11*11+7;		if(dlm)			magic |= 0x80000000;		lput(magic);			/* 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:		/* MS-DOS .COM */		break;	case 4:		/* fake MS-DOS .EXE */		v = rnd(HEADR+textsize, INITRND)+datsize;		wputl(0x5A4D);			/* 'MZ' */		wputl(v % 512);			/* bytes in last page */		wputl(rnd(v, 512)/512);		/* total number of pages */		wputl(0x0000);			/* number of reloc items */		v = rnd(HEADR-(INITTEXT & 0xFFFF), 16);		wputl(v/16);			/* size of header */		wputl(0x0000);			/* minimum allocation */		wputl(0xFFFF);			/* maximum allocation */		wputl(0x0000);			/* initial ss value */		wputl(0x0100);			/* initial sp value */		wputl(0x0000);			/* complemented checksum */		v = entryvalue();		wputl(v);			/* initial ip value (!) */		wputl(0x0000);			/* initial cs value */		wputl(0x0000);		wputl(0x0000);		wputl(0x003E);			/* reloc table offset */		wputl(0x0000);			/* overlay number */		break;	case 5:		strnput("\177ELF", 4);		/* e_ident */		cput(1);			/* class = 32 bit */		cput(1);			/* data = LSB */		cput(1);			/* version = CURRENT */		strnput("", 9);		wputl(2);			/* type = EXEC */		wputl(3);			/* machine = 386 */		lputl(1L);			/* version = CURRENT */		lputl(PADDR(entryvalue()));	/* entry vaddr */		lputl(52L);			/* offset to first phdr */		lputl(0L);			/* offset to first shdr */		lputl(0L);			/* flags = 386 */		wputl(52);			/* Ehdr size */		wputl(32);			/* Phdr size */		wputl(3);			/* # of Phdrs */		wputl(0);			/* Shdr size */		wputl(0);			/* # of Shdrs */		wputl(0);			/* Shdr string size */		lputl(1L);			/* text - type = PT_LOAD */		lputl(HEADR);			/* file offset */		lputl(INITTEXT);		/* vaddr */		lputl(PADDR(INITTEXT));		/* paddr */		lputl(textsize);		/* file size */		lputl(textsize);		/* memory size */		lputl(0x05L);			/* protections = RX */		lputl(INITRND);			/* alignment */		lputl(1L);			/* data - type = PT_LOAD */		lputl(HEADR+textsize);		/* file offset */		lputl(INITDAT);			/* vaddr */		lputl(PADDR(INITDAT));		/* paddr */		lputl(datsize);			/* file size */		lputl(datsize+bsssize);		/* memory size */		lputl(0x06L);			/* protections = RW */		lputl(INITRND);			/* alignment */		lputl(0L);			/* data - type = PT_NULL */		lputl(HEADR+textsize+datsize);	/* file offset */		lputl(0L);		lputl(0L);		lputl(symsize);			/* symbol table size */		lputl(lcsize);			/* line number size */		lputl(0x04L);			/* protections = R */		lputl(0x04L);			/* alignment */		break;	}	cflush();}voidcflush(void){	int n;	n = sizeof(buf.cbuf) - cbc;	if(n)		write(cout, buf.cbuf, n);	cbp = buf.cbuf;	cbc = sizeof(buf.cbuf);}voiddatblk(long s, long n){	Prog *p;	char *cast;	long l, fl, j;	int i, c;	memset(buf.dbuf, 0, n+Dbufslop);	for(p = datap; p != P; p = p->link) {		curp = p;		l = p->from.sym->value + p->from.offset - s;		c = p->from.scale;		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) {		case D_FCONST:			switch(c) {			default:			case 4:				fl = ieeedtof(&p->to.ieee);				cast = (char*)&fl;				if(debug['a'] && i == 0) {					Bprint(&bso, pcstr, l+s+INITDAT);					for(j=0; j<c; j++)						Bprint(&bso, "%.2ux", cast[fnuxi4[j]] & 0xff);					Bprint(&bso, "\t%P\n", curp);				}				for(; i<c; i++) {					buf.dbuf[l] = cast[fnuxi4[i]];					l++;				}				break;			case 8:				cast = (char*)&p->to.ieee;				if(debug['a'] && i == 0) {					Bprint(&bso, pcstr, l+s+INITDAT);					for(j=0; j<c; j++)						Bprint(&bso, "%.2ux", cast[fnuxi8[j]] & 0xff);					Bprint(&bso, "\t%P\n", curp);				}				for(; i<c; i++) {					buf.dbuf[l] = cast[fnuxi8[i]];					l++;				}				break;			}			break;		case D_SCONST:			if(debug['a'] && i == 0) {				Bprint(&bso, pcstr, l+s+INITDAT);				for(j=0; j<c; j++)					Bprint(&bso, "%.2ux", p->to.scon[j] & 0xff);				Bprint(&bso, "\t%P\n", curp);			}			for(; i<c; i++) {				buf.dbuf[l] = p->to.scon[i];				l++;			}			break;		default:			fl = p->to.offset;			if(p->to.type == D_ADDR) {				if(p->to.index != D_STATIC && p->to.index != D_EXTERN)					diag("DADDR type%P", p);				if(p->to.sym) {					if(p->to.sym->type == SUNDEF)						ckoff(p->to.sym, fl);					fl += p->to.sym->value;					if(p->to.sym->type != STEXT && p->to.sym->type != SUNDEF)						fl += INITDAT;					if(dlm)						dynreloc(p->to.sym, l+s+INITDAT, 1);				}			}			cast = (char*)&fl;			switch(c) {			default:				diag("bad nuxi %d %d\n%P", c, i, curp);				break;			case 1:				if(debug['a'] && i == 0) {					Bprint(&bso, pcstr, l+s+INITDAT);					for(j=0; j<c; j++)						Bprint(&bso, "%.2ux", cast[inuxi1[j]] & 0xff);					Bprint(&bso, "\t%P\n", curp);				}				for(; i<c; i++) {					buf.dbuf[l] = cast[inuxi1[i]];					l++;				}				break;			case 2:				if(debug['a'] && i == 0) {					Bprint(&bso, pcstr, l+s+INITDAT);					for(j=0; j<c; j++)						Bprint(&bso, "%.2ux", cast[inuxi2[j]] & 0xff);					Bprint(&bso, "\t%P\n", curp);				}				for(; i<c; i++) {					buf.dbuf[l] = cast[inuxi2[i]];					l++;				}				break;			case 4:				if(debug['a'] && i == 0) {					Bprint(&bso, pcstr, l+s+INITDAT);					for(j=0; j<c; j++)						Bprint(&bso, "%.2ux", cast[inuxi4[j]] & 0xff);					Bprint(&bso, "\t%P\n", curp);				}				for(; i<c; i++) {					buf.dbuf[l] = cast[inuxi4[i]];					l++;				}				break;			}			break;		}	}	write(cout, buf.dbuf, n);}longrnd(long v, long r){	long c;	if(r <= 0)		return v;	v += r - 1;	c = v % r;	if(c < 0)		c += r;	v -= c;	return v;}

⌨️ 快捷键说明

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