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

📄 span.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
	APOPW,	Ynone,	Yds,	0,	Pe,0x1f,E,0,	APOPW,	Ynone,	Yes,	0,	Pe,0x07,E,0,	APOPW,	Ynone,	Yss,	0,	Pe,0x17,E,0,	APOPW,	Ynone,	Yfs,	0,	Pe,0x0f,0xa1,E,	APOPW,	Ynone,	Ygs,	0,	Pe,0x0f,0xa9,E,/* mov seg */	AMOVW,	Yes,	Yml,	1,	0x8c,0,0,0,	AMOVW,	Ycs,	Yml,	1,	0x8c,1,0,0,	AMOVW,	Yss,	Yml,	1,	0x8c,2,0,0,	AMOVW,	Yds,	Yml,	1,	0x8c,3,0,0,	AMOVW,	Yfs,	Yml,	1,	0x8c,4,0,0,	AMOVW,	Ygs,	Yml,	1,	0x8c,5,0,0,	AMOVW,	Yml,	Yes,	2,	0x8e,0,0,0,	AMOVW,	Yml,	Ycs,	2,	0x8e,1,0,0,	AMOVW,	Yml,	Yss,	2,	0x8e,2,0,0,	AMOVW,	Yml,	Yds,	2,	0x8e,3,0,0,	AMOVW,	Yml,	Yfs,	2,	0x8e,4,0,0,	AMOVW,	Yml,	Ygs,	2,	0x8e,5,0,0,/* mov cr */	AMOVL,	Ycr0,	Yml,	3,	0x0f,0x20,0,0,	AMOVL,	Ycr2,	Yml,	3,	0x0f,0x20,2,0,	AMOVL,	Ycr3,	Yml,	3,	0x0f,0x20,3,0,	AMOVL,	Ycr4,	Yml,	3,	0x0f,0x20,4,0,	AMOVL,	Yml,	Ycr0,	4,	0x0f,0x22,0,0,	AMOVL,	Yml,	Ycr2,	4,	0x0f,0x22,2,0,	AMOVL,	Yml,	Ycr3,	4,	0x0f,0x22,3,0,	AMOVL,	Yml,	Ycr4,	4,	0x0f,0x22,4,0,/* mov dr */	AMOVL,	Ydr0,	Yml,	3,	0x0f,0x21,0,0,	AMOVL,	Ydr6,	Yml,	3,	0x0f,0x21,6,0,	AMOVL,	Ydr7,	Yml,	3,	0x0f,0x21,7,0,	AMOVL,	Yml,	Ydr0,	4,	0x0f,0x23,0,0,	AMOVL,	Yml,	Ydr6,	4,	0x0f,0x23,6,0,	AMOVL,	Yml,	Ydr7,	4,	0x0f,0x23,7,0,/* mov tr */	AMOVL,	Ytr6,	Yml,	3,	0x0f,0x24,6,0,	AMOVL,	Ytr7,	Yml,	3,	0x0f,0x24,7,0,	AMOVL,	Yml,	Ytr6,	4,	0x0f,0x26,6,E,	AMOVL,	Yml,	Ytr7,	4,	0x0f,0x26,7,E,/* lgdt, sgdt, lidt, sidt */	AMOVL,	Ym,	Ygdtr,	4,	0x0f,0x01,2,0,	AMOVL,	Ygdtr,	Ym,	3,	0x0f,0x01,0,0,	AMOVL,	Ym,	Yidtr,	4,	0x0f,0x01,3,0,	AMOVL,	Yidtr,	Ym,	3,	0x0f,0x01,1,0,/* lldt, sldt */	AMOVW,	Yml,	Yldtr,	4,	0x0f,0x00,2,0,	AMOVW,	Yldtr,	Yml,	3,	0x0f,0x00,0,0,/* lmsw, smsw */	AMOVW,	Yml,	Ymsw,	4,	0x0f,0x01,6,0,	AMOVW,	Ymsw,	Yml,	3,	0x0f,0x01,4,0,/* ltr, str */	AMOVW,	Yml,	Ytask,	4,	0x0f,0x00,3,0,	AMOVW,	Ytask,	Yml,	3,	0x0f,0x00,1,0,/* load full pointer */	AMOVL,	Yml,	Ycol,	5,	0,0,0,0,	AMOVW,	Yml,	Ycol,	5,	Pe,0,0,0,/* double shift */	ASHLL,	Ycol,	Yml,	6,	0xa4,0xa5,0,0,	ASHRL,	Ycol,	Yml,	6,	0xac,0xad,0,0,/* extra imul */	AIMULL,	Yml,	Yrl,	7,	Pm,0xaf,0,0,	0};intisax(Adr *a){	switch(a->type) {	case D_AX:	case D_AL:	case D_AH:	case D_INDIR+D_AX:		return 1;	}	if(a->index == D_AX)		return 1;	return 0;}voidsubreg(Prog *p, int from, int to){	if(debug['Q'])		print("\n%P	s/%R/%R/\n", p, from, to);	if(p->from.type == from)		p->from.type = to;	if(p->to.type == from)		p->to.type = to;	if(p->from.index == from)		p->from.index = to;	if(p->to.index == from)		p->to.index = to;	from += D_INDIR;	if(p->from.type == from)		p->from.type = to+D_INDIR;	if(p->to.type == from)		p->to.type = to+D_INDIR;	if(debug['Q'])		print("%P\n", p);}voiddoasm(Prog *p){	Optab *o;	Prog *q, pp;	uchar *t;	int z, op, ft, tt;	long v;	o = &optab[p->as];	ft = oclass(&p->from) * Ymax;	tt = oclass(&p->to) * Ymax;	t = o->ytab;	if(t == 0) {		diag("asmins: noproto %P", p);		return;	}	for(z=0; *t; z+=t[3],t+=4)		if(ycover[ft+t[0]])		if(ycover[tt+t[1]])			goto found;	goto domov;found:	switch(o->prefix) {	case Pq:	/* 16 bit escape and opcode escape */		*andptr++ = Pe;		*andptr++ = Pm;		break;	case Pm:	/* opcode escape */		*andptr++ = Pm;		break;	case Pe:	/* 16 bit escape */		*andptr++ = Pe;		break;	case Pb:	/* botch */		break;	}	v = vaddr(&p->from);	op = o->op[z];	switch(t[2]) {	default:		diag("asmins: unknown z %d %P", t[2], p);		return;	case Zpseudo:		break;	case Zlit:		for(; op = o->op[z]; z++)			*andptr++ = op;		break;	case Zm_r:		*andptr++ = op;		asmand(&p->from, reg[p->to.type]);		break;	case Zaut_r:		*andptr++ = 0x8d;	/* leal */		if(p->from.type != D_ADDR)			diag("asmins: Zaut sb type ADDR");		p->from.type = p->from.index;		p->from.index = D_NONE;		asmand(&p->from, reg[p->to.type]);		p->from.index = p->from.type;		p->from.type = D_ADDR;		break;	case Zm_o:		*andptr++ = op;		asmand(&p->from, o->op[z+1]);		break;	case Zr_m:		*andptr++ = op;		asmand(&p->to, reg[p->from.type]);		break;	case Zo_m:		*andptr++ = op;		asmand(&p->to, o->op[z+1]);		break;	case Zm_ibo:		v = vaddr(&p->to);		*andptr++ = op;		asmand(&p->from, o->op[z+1]);		*andptr++ = v;		break;	case Zibo_m:		*andptr++ = op;		asmand(&p->to, o->op[z+1]);		*andptr++ = v;		break;	case Z_ib:		v = vaddr(&p->to);	case Zib_:		*andptr++ = op;		*andptr++ = v;		break;	case Zib_rp:		*andptr++ = op + reg[p->to.type];		*andptr++ = v;		break;	case Zil_rp:		*andptr++ = op + reg[p->to.type];		if(o->prefix == Pe) {			*andptr++ = v;			*andptr++ = v>>8;		}		else			put4(v);		break;	case Zib_rr:		*andptr++ = op;		asmand(&p->to, reg[p->to.type]);		*andptr++ = v;		break;	case Z_il:		v = vaddr(&p->to);	case Zil_:		*andptr++ = op;		if(o->prefix == Pe) {			*andptr++ = v;			*andptr++ = v>>8;		}		else			put4(v);		break;	case Zm_ilo:		v = vaddr(&p->to);		*andptr++ = op;		asmand(&p->from, o->op[z+1]);		if(o->prefix == Pe) {			*andptr++ = v;			*andptr++ = v>>8;		}		else			put4(v);		break;	case Zilo_m:		*andptr++ = op;		asmand(&p->to, o->op[z+1]);		if(o->prefix == Pe) {			*andptr++ = v;			*andptr++ = v>>8;		}		else			put4(v);		break;	case Zil_rr:		*andptr++ = op;		asmand(&p->to, reg[p->to.type]);		if(o->prefix == Pe) {			*andptr++ = v;			*andptr++ = v>>8;		}		else			put4(v);		break;	case Z_rp:		*andptr++ = op + reg[p->to.type];		break;	case Zrp_:		*andptr++ = op + reg[p->from.type];		break;	case Zclr:		*andptr++ = op;		asmand(&p->to, reg[p->to.type]);		break;	case Zbr:		q = p->pcond;		if(q) {			v = q->pc - p->pc - 2;			if(v >= -128 && v <= 127) {				*andptr++ = op;				*andptr++ = v;			} else {				v -= 6-2;				*andptr++ = 0x0f;				*andptr++ = o->op[z+1];				*andptr++ = v;				*andptr++ = v>>8;				*andptr++ = v>>16;				*andptr++ = v>>24;			}		}		break;	case Zcall:		q = p->pcond;		if(q) {			v = q->pc - p->pc - 5;			if(dlm && curp != P && p->to.sym->type == SUNDEF){				/* v = 0 - p->pc - 5; */				v = 0;				ckoff(p->to.sym, v);				v += p->to.sym->value;				dynreloc(p->to.sym, p->pc+1, 0);			}			*andptr++ = op;			*andptr++ = v;			*andptr++ = v>>8;			*andptr++ = v>>16;			*andptr++ = v>>24;		}		break;	case Zjmp:		q = p->pcond;		if(q) {			v = q->pc - p->pc - 2;			if(v >= -128 && v <= 127) {				*andptr++ = op;				*andptr++ = v;			} else {				v -= 5-2;				*andptr++ = o->op[z+1];				*andptr++ = v;				*andptr++ = v>>8;				*andptr++ = v>>16;				*andptr++ = v>>24;			}		}		break;	case Zloop:		q = p->pcond;		if(q) {			v = q->pc - p->pc - 2;			if(v < -128 && v > 127)				diag("loop too far: %P", p);			*andptr++ = op;			*andptr++ = v;		}		break;	case Zbyte:		*andptr++ = v;		if(op > 1) {			*andptr++ = v>>8;			if(op > 2) {				*andptr++ = v>>16;				*andptr++ = v>>24;			}		}		break;	case Zmov:		goto domov;	}	return;domov:	for(t=ymovtab; *t; t+=8)		if(p->as == t[0])		if(ycover[ft+t[1]])		if(ycover[tt+t[2]])			goto mfound;bad:	/*	 * here, the assembly has failed.	 * if its a byte instruction that has	 * unaddressable registers, try to	 * exchange registers and reissue the	 * instruction with the operands renamed.	 */	pp = *p;	z = p->from.type;	if(z >= D_BP && z <= D_DI) {		if(isax(&p->to)) {			*andptr++ = 0x87;			/* xchg lhs,bx */			asmand(&p->from, reg[D_BX]);			subreg(&pp, z, D_BX);			doasm(&pp);			*andptr++ = 0x87;			/* xchg lhs,bx */			asmand(&p->from, reg[D_BX]);		} else {			*andptr++ = 0x90 + reg[z];		/* xchg lsh,ax */			subreg(&pp, z, D_AX);			doasm(&pp);			*andptr++ = 0x90 + reg[z];		/* xchg lsh,ax */		}		return;	}	z = p->to.type;	if(z >= D_BP && z <= D_DI) {		if(isax(&p->from)) {			*andptr++ = 0x87;			/* xchg rhs,bx */			asmand(&p->to, reg[D_BX]);			subreg(&pp, z, D_BX);			doasm(&pp);			*andptr++ = 0x87;			/* xchg rhs,bx */			asmand(&p->to, reg[D_BX]);		} else {			*andptr++ = 0x90 + reg[z];		/* xchg rsh,ax */			subreg(&pp, z, D_AX);			doasm(&pp);			*andptr++ = 0x90 + reg[z];		/* xchg rsh,ax */		}		return;	}	diag("doasm: notfound t2=%lux from=%lux to=%lux %P", t[2], p->from.type, p->to.type, p);	return;mfound:	switch(t[3]) {	default:		diag("asmins: unknown mov %d %P", t[3], p);		break;	case 0:	/* lit */		for(z=4; t[z]!=E; z++)			*andptr++ = t[z];		break;	case 1:	/* r,m */		*andptr++ = t[4];		asmand(&p->to, t[5]);		break;	case 2:	/* m,r */		*andptr++ = t[4];		asmand(&p->from, t[5]);		break;	case 3:	/* r,m - 2op */		*andptr++ = t[4];		*andptr++ = t[5];		asmand(&p->to, t[6]);		break;	case 4:	/* m,r - 2op */		*andptr++ = t[4];		*andptr++ = t[5];		asmand(&p->from, t[6]);		break;	case 5:	/* load full pointer, trash heap */		if(t[4])			*andptr++ = t[4];		switch(p->to.index) {		default:			goto bad;		case D_DS:			*andptr++ = 0xc5;			break;		case D_SS:			*andptr++ = 0x0f;			*andptr++ = 0xb2;			break;		case D_ES:			*andptr++ = 0xc4;			break;		case D_FS:			*andptr++ = 0x0f;			*andptr++ = 0xb4;			break;		case D_GS:			*andptr++ = 0x0f;			*andptr++ = 0xb5;			break;		}		asmand(&p->from, reg[p->to.type]);		break;	case 6:	/* double shift */		z = p->from.type;		switch(z) {		default:			goto bad;		case D_CONST:			*andptr++ = 0x0f;			*andptr++ = t[4];			asmand(&p->to, reg[p->from.index]);			*andptr++ = p->from.offset;			break;		case D_CL:		case D_CX:			*andptr++ = 0x0f;			*andptr++ = t[5];			asmand(&p->to, reg[p->from.index]);			break;		}		break;	case 7: /* imul rm,r */		*andptr++ = t[4];		*andptr++ = t[5];		asmand(&p->from, reg[p->to.type]);		break;	}}voidasmins(Prog *p){	andptr = and;	doasm(p);}enum{	ABSD = 0,	ABSU = 1,	RELD = 2,	RELU = 3,};int modemap[4] = { 0, 1, -1, 2, };typedef struct Reloc Reloc;struct Reloc{	int n;	int t;	uchar *m;	ulong *a;};Reloc rels;static voidgrow(Reloc *r){	int t;	uchar *m, *nm;	ulong *a, *na;	t = r->t;	r->t += 64;	m = r->m;	a = r->a;	r->m = nm = malloc(r->t*sizeof(uchar));	r->a = na = malloc(r->t*sizeof(ulong));	memmove(nm, m, t*sizeof(uchar));	memmove(na, a, t*sizeof(ulong));	free(m);	free(a);}voiddynreloc(Sym *s, ulong v, int abs){	int i, k, n;	uchar *m;	ulong *a;	Reloc *r;	if(s->type == SUNDEF)		k = abs ? ABSU : RELU;	else		k = abs ? ABSD : RELD;	/* Bprint(&bso, "R %s a=%ld(%lx) %d\n", s->name, v, v, k); */	k = modemap[k];	r = &rels;	n = r->n;	if(n >= r->t)		grow(r);	m = r->m;	a = r->a;	for(i = n; i > 0; i--){		if(v < a[i-1]){	/* happens occasionally for data */			m[i] = m[i-1];			a[i] = a[i-1];		}		else			break;	}	m[i] = k;	a[i] = v;	r->n++;}static intsput(char *s){	char *p;	p = s;	while(*s)		cput(*s++);	cput(0);	return s-p+1;}voidasmdyn(){	int i, n, t, c;	Sym *s;	ulong la, ra, *a;	vlong off;	uchar *m;	Reloc *r;	cflush();	off = seek(cout, 0, 1);	lput(0);	t = 0;	lput(imports);	t += 4;	for(i = 0; i < NHASH; i++)		for(s = hash[i]; s != S; s = s->link)			if(s->type == SUNDEF){				lput(s->sig);				t += 4;				t += sput(s->name);			}	la = 0;	r = &rels;	n = r->n;	m = r->m;	a = r->a;	lput(n);	t += 4;	for(i = 0; i < n; i++){		ra = *a-la;		if(*a < la)			diag("bad relocation order");		if(ra < 256)			c = 0;		else if(ra < 65536)			c = 1;		else			c = 2;		cput((c<<6)|*m++);		t++;		if(c == 0){			cput(ra);			t++;		}		else if(c == 1){			wput(ra);			t += 2;		}		else{			lput(ra);			t += 4;		}		la = *a++;	}	cflush();	seek(cout, off, 0);	lput(t);	if(debug['v']){		Bprint(&bso, "import table entries = %d\n", imports);		Bprint(&bso, "export table entries = %d\n", exports);	}}

⌨️ 快捷键说明

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