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

📄 symbol.c

📁 MCS51系列单片机的汇编器
💻 C
字号:
/* ---------------------------------------------------------------------- * FILE: symbol.c * PACKAGE: as31 - 8031/8051 Assembler. * * DESCRIPTION: *	This file contains the symbol table search/insertion routines *	associated with user defined symbols. * *	The reserved keyword (instructions/directives) look up routine *	is defined here. * *	The opcode table for all of the instructions is located in this *	file. * * REVISION HISTORY: *	Jan. 19, 1990 - Created. (Ken Stauffer) * * AUTHOR: *	All code in this file written by Ken Stauffer (University of Calgary) *	January, 1990. * */#include <ctype.h>#include <string.h>/* normally in stdlib.h, but that include file also defines *//* "div" which conflicts with the div in this file */extern void *malloc(size_t size);extern void free(void *ptr);#include "as31.h"#include "parser.h"#define B(a)		(0xF0+(a))#define ACC(a)		(0xE0+(a))#define PSW(a)		(0xD0+(a))#define T2CON(a)	(0xC8+(a))#define IP(a)		(0xB8+(a))#define P3(a)		(0xB0+(a))#define IE(a)		(0xA8+(a))#define P2(a)		(0xA0+(a))#define SCON(a)		(0x98+(a))#define P1(a)		(0x90+(a))#define TCON(a)		(0x88+(a))#define P0(a)		(0x80+(a))/* ----------------------------------------------------------------------  * sinit[] *	These symbols are not reserved keywords. *	This array contains the initial symbol table entries *	for the user symbol table. The symbols are *	basically convienient names that make writing *	in 8031/8051 bearable. * *	The function syminit() inserts these entries into the *	symbol table. * */static struct symbol sinit[] = {	{ "AC",		1, LABEL,		PSW(6),	NULL },	{ "ACC",	1, LABEL,		ACC(0),	NULL },	{ "B",		1, LABEL,		B(0),	NULL },	{ "CY",		1, LABEL,		PSW(7),	NULL },	{ "DPH",	1, LABEL,		0x83,	NULL },	{ "DPL",	1, LABEL,		0x82,	NULL },	{ "EA",		1, LABEL,		IE(7),	NULL },	{ "ES",		1, LABEL,		IE(4),	NULL },	{ "ET0",	1, LABEL,		IE(1),	NULL },	{ "ET1",	1, LABEL,		IE(3),	NULL },	{ "ET2",	1, LABEL,		IE(5),	NULL },	{ "EX0",	1, LABEL,		IE(0),	NULL },	{ "EX1",	1, LABEL,		IE(2),	NULL },	{ "EXEN2",	1, LABEL,		T2CON(3),NULL },	{ "EXF2",	1, LABEL,		T2CON(6),NULL },	{ "F0",		1, LABEL,		PSW(5),	NULL },	{ "IE",		1, LABEL,		IE(0),	NULL },	{ "IE0",	1, LABEL,		TCON(1),NULL },	{ "IE1",	1, LABEL,		TCON(3),NULL },	{ "INT0",	1, LABEL,		P3(2),  NULL },	{ "INT1",	1, LABEL,		P3(3),  NULL },	{ "IP",		1, LABEL,		IP(0),	NULL },	{ "IT0",	1, LABEL,		TCON(0),NULL },	{ "IT1",	1, LABEL,		TCON(2),NULL },	{ "OV",		1, LABEL,		PSW(2),	NULL },	{ "P",		1, LABEL,		PSW(0),	NULL },	{ "P0",		1, LABEL,		P0(0),	NULL },	{ "P1",		1, LABEL,		P1(0),	NULL },	{ "P2",		1, LABEL,		P2(0),	NULL },	{ "P3",		1, LABEL,		P3(0),	NULL },	{ "PCON",	1, LABEL,		0x87,	NULL },	{ "PS",		1, LABEL,		IP(4),	NULL },	{ "PSW",	1, LABEL,		PSW(0),	NULL },	{ "PT0",	1, LABEL,		IP(1),	NULL },	{ "PT1",	1, LABEL,		IP(3),	NULL },	{ "PT2",	1, LABEL,		IP(5),	NULL },	{ "PX0",	1, LABEL,		IP(0),	NULL },	{ "PX1",	1, LABEL,		IP(2),	NULL },	{ "RB8",	1, LABEL,		SCON(2),NULL },	{ "RCAP2H",	1, LABEL,		0xCB,	NULL },	{ "RCAP2L",	1, LABEL,		0xCA,	NULL },	{ "RCLK",	1, LABEL,		T2CON(5),NULL },	{ "REN",	1, LABEL,		SCON(4),NULL },	{ "RD",		1, LABEL,		P3(7),  NULL },	{ "RI",		1, LABEL,		SCON(0),NULL },	{ "RL2",	1, LABEL,		T2CON(0),NULL },	{ "RS0",	1, LABEL,		PSW(3),	NULL },	{ "RS1",	1, LABEL,		PSW(4),	NULL },	{ "RXD",	1, LABEL,		P3(0),  NULL },	{ "SBUF",	1, LABEL,		0x99,	NULL },	{ "SCON",	1, LABEL,		SCON(0),NULL },	{ "SM0",	1, LABEL,		SCON(7),NULL },	{ "SM1",	1, LABEL,		SCON(6),NULL },	{ "SM2",	1, LABEL,		SCON(5),NULL },	{ "SP",		1, LABEL,		0x81,	NULL },	{ "T0",		1, LABEL,		P3(4),  NULL },	{ "T1",		1, LABEL,		P3(5),  NULL },	{ "T2",		1, LABEL,		P0(0),  NULL },	{ "T2CON",	1, LABEL,		T2CON(0),NULL },	{ "T2EX",	1, LABEL,		P0(1),  NULL },	{ "TB8",	1, LABEL,		SCON(3),NULL },	{ "TCLK",	1, LABEL,		T2CON(4),NULL },	{ "TCON",	1, LABEL,		TCON(0),NULL },	{ "TF0",	1, LABEL,		TCON(5),NULL },	{ "TF1",	1, LABEL,		TCON(7),NULL },	{ "TF2",	1, LABEL,		T2CON(7),NULL },	{ "TH0",	1, LABEL,		0x8C,	NULL },	{ "TH1",	1, LABEL,		0x8D,	NULL },	{ "TH2",	1, LABEL,		0xCD,	NULL },	{ "TI",		1, LABEL,		SCON(1),NULL },	{ "TL0",	1, LABEL,		0x8A,	NULL },	{ "TL1",	1, LABEL,		0x8B,	NULL },	{ "TL2",	1, LABEL,		0xCC,	NULL },	{ "TMOD",	1, LABEL,		0x89,	NULL },	{ "TR0",	1, LABEL,		TCON(4),NULL },	{ "TR1",	1, LABEL,		TCON(6),NULL },	{ "TR2",	1, LABEL,		T2CON(2),NULL },	{ "TXD",	1, LABEL,		P3(1),  NULL },	{ "WR",		1, LABEL,		P3(6),	NULL }};#define SINITSIZE	(sizeof(sinit)/sizeof(sinit[0]))/* ---------------------------------------------------------------------- * opcode vectors: *	These arrays contain the various opcodes for the *	various forms an instruction may take. * *	The ordering of these opcodes is very critical to the *	proper fuctioning of the assembler. * *	When a given form of an instruction is parsed, the parser *	indexes one of these arrays by the correct amount and thus *	obtains the correct opcode for the particular form. * */static unsigned char acall[]=	{ 0x11 };static unsigned char add[]=	{ 0x28, 0x25, 0x26, 0x24 };static unsigned char addc[]=	{ 0x38, 0x35, 0x36, 0x34 };static unsigned char ajmp[]=	{ 0x01 };static unsigned char anl[]=	{ 0x58, 0x55, 0x56, 0x54, 0x52, 0x53, 0x82,				  0xb0 };static unsigned char cjne[]=	{ 0xb5, 0xb4, 0xb8, 0xb6 };static unsigned char clr[]=	{ 0xe4, 0xc3, 0xc2 };static unsigned char cpl[]=	{ 0xf4, 0xb3, 0xb2 };static unsigned char da[]=	{ 0xd4 };static unsigned char dec[]=	{ 0x14, 0x18, 0x15, 0x16 };static unsigned char div[]=	{ 0x84 };static unsigned char djnz[]=	{ 0xd8, 0xd5 };static unsigned char inc[]=	{ 0x04, 0x08, 0x05, 0x06, 0xa3 };static unsigned char jb[]=	{ 0x20 };static unsigned char jbc[]=	{ 0x10 };static unsigned char jc[]=	{ 0x40 };static unsigned char jmp[]=	{ 0x73 };static unsigned char jnb[]=	{ 0x30 };static unsigned char jnc[]=	{ 0x50 };static unsigned char jnz[]=	{ 0x70 };static unsigned char jz[]=	{ 0x60 };static unsigned char lcall[]=	{ 0x12 };static unsigned char ljmp[]=	{ 0x02 };static unsigned char mov[]=	{ 0xe8, 0xe5, 0xe6, 0x74, 0xf5, 0x75, 0xf8,				  0xa8, 0x78, 0x88, 0x85, 0x86, 0xf6, 0xa6,				  0x76, 0x90, 0xa2, 0x92 };static unsigned char movc[]=	{ 0x93, 0x83 };static unsigned char movx[]=	{ 0xe2, 0xe3, 0xe0, 0xf2, 0xf3, 0xf0 };static unsigned char mul[]=	{ 0xa4 };static unsigned char nop[]=	{ 0x00 };static unsigned char orl[]=	{ 0x48, 0x45, 0x46, 0x44, 0x42, 0x43, 0x72,				  0xa0 };static unsigned char pop[]=	{ 0xd0 };static unsigned char push[]=	{ 0xc0 };static unsigned char ret[]=	{ 0x22 };static unsigned char reti[]=	{ 0x32 };static unsigned char rl[]=	{ 0x23 };static unsigned char rlc[]=	{ 0x33 };static unsigned char rr[]=	{ 0x03 };static unsigned char rrc[]=	{ 0x13 };static unsigned char setb[]=	{ 0xd3, 0xd2 };static unsigned char sjmp[]=	{ 0x80 };static unsigned char subb[]=	{ 0x98, 0x95, 0x96, 0x94 };static unsigned char swap[]=	{ 0xc4 };static unsigned char xch[]=	{ 0xc8, 0xc5, 0xc6 };static unsigned char xchd[]=	{ 0xd6 };static unsigned char xrl[]=	{ 0x68, 0x65, 0x66, 0x64, 0x62, 0x63 };/* ---------------------------------------------------------------------- * optable[] *	This table contains opcodes, directives and a few reserved *	symbols. * *	The second field is the keywords token value. * *	Unless the symbol is an opcode, the third field will *	be NULL. *  *	The third field is a pointer to an array of opcode bytes. * *    --> This list must be in order by the first field */static struct opcode optable[] = {	{"a",		A,	NULL		},	{"ab",		AB,	NULL		},	{"acall",	ACALL,	acall		},	{"add",		ADD,	add		},	{"addc",	ADDC,	addc		},	{"ajmp",	AJMP,	ajmp		},	{"anl",		ANL,	anl		},	{"byte",	D_BYTE,	NULL		},	{"c",		C,	NULL		},	{"cjne",	CJNE,	cjne		},	{"clr",		CLR,	clr		},	{"cpl",		CPL,	cpl		},	{"da",		DA,	da		},	{"db",		D_BYTE,	NULL		},	{"dec",		DEC,	dec		},	{"div",		DIV,	div		},	{"djnz",	DJNZ,	djnz		},	{"dptr",	DPTR,	NULL		},	{"dw",		D_WORD, NULL		},	{"end",		D_END,	NULL		},	{"equ",		D_EQU,	NULL		},	{"flag",	D_FLAG,	NULL		},	{"inc",		INC,	inc		},	{"jb",		JB,	jb		},	{"jbc",		JBC,	jbc		},	{"jc",		JC,	jc		},	{"jmp",		JMP,	jmp		},	{"jnb",		JNB,	jnb		},	{"jnc",		JNC,	jnc		},	{"jnz",		JNZ,	jnz		},	{"jz",		JZ,	jz		},	{"lcall",	LCALL,	lcall		},	{"ljmp",	LJMP,	ljmp		},	{"mov",		MOV,	mov		},	{"movc",	MOVC,	movc		},	{"movx",	MOVX,	movx		},	{"mul",		MUL,	mul		},	{"nop",		NOP,	nop		},	{"org",		D_ORG,	NULL		},	{"orl",		ORL,	orl		},	{"pc",		PC,	NULL		},	{"pop",		POP,	pop		},	{"push",	PUSH,	push		},	{"r0",		R0,	NULL		},	{"r1",		R1,	NULL		},	{"r2",		R2,	NULL		},	{"r3",		R3,	NULL		},	{"r4",		R4,	NULL		},	{"r5",		R5,	NULL		},	{"r6",		R6,	NULL		},	{"r7",		R7,	NULL		},	{"ret",		RET,	ret		},	{"reti",	RETI,	reti		},	{"rl",		RL,	rl		},	{"rlc",		RLC,	rlc		},	{"rr",		RR,	rr		},	{"rrc",		RRC,	rrc		},	{"setb",	SETB,	setb		},	{"sjmp",	SJMP,	sjmp		},	{"skip",	D_SKIP,	NULL		},	{"subb",	SUBB,	subb		},	{"swap",	SWAP,	swap		},	{"word",	D_WORD,	NULL		},	{"xch",		XCH,	xch		},	{"xchd",	XCHD,	xchd		},	{"xrl",		XRL,	xrl		}};#define OPTABSIZE	(sizeof(optable)/sizeof(struct opcode))/* ---------------------------------------------------------------------- * lookop: *	Do a binary search through optable[], for a matching *	symbol. Return the symbol found or NULL. * */struct opcode *lookop(const char *s){	register int low,high,mid,cond;	low = 0;	high = OPTABSIZE-1;	while( low<=high ) {		mid = (low+high)/2;		if( (cond = strcasecmp(s,optable[mid].name)) < 0 )			high = mid-1;		else if(cond > 0 )			low = mid+1;		else			return(&optable[mid]);	}	return(NULL);}/* ---------------------------------------------------------------------- * symtab, hash, looksym: *	User symbol table routines. *	symtab is the hash table for the user symbols. *	(chaining is used for collision resolution). * */static struct symbol *symtab[HASHTABSIZE];int hash(const char *s){	register const char *p;	register unsigned h=0, g;	for (p=s; *p; p++) {		h = (h<<4) + toupper(*p);		if ( (g = h&0xf0000000) ) {			h = h ^ (g >> 24);			h = h ^ g;		}	}	return( h % HASHTABSIZE );}struct symbol *looksym(const char *s){	register struct symbol *ptr, *prev;	char *p;	register int hv;	hv = hash(s);	prev = NULL;	for(ptr=symtab[hv]; ptr; ptr = ptr->next) {		if( !strcasecmp(ptr->name,s) ) {			if( prev != NULL ) {				prev->next = ptr->next;				ptr->next = symtab[hv];				symtab[hv] = ptr;			}			return(ptr);		}		prev = ptr;	}	if ( (p = malloc(strlen(s) + 1)) ) {		strcpy(p,s);	} else {		error("Cannot allocate %d bytes",strlen(s)+1);	}	ptr = (struct symbol *) malloc( sizeof(struct symbol) );	if( ptr == NULL )		error("Cannot allocate %d bytes",sizeof(struct symbol));	ptr->name = p;	ptr->predefined = 0;	ptr->type = UNDEF;	ptr->next = symtab[hv];	symtab[hv] = ptr;	return(ptr);}/* ---------------------------------------------------------------------- * syminit: *	Initializes the hash table, with the initial symbols from *	sinit[] * */// static struct symbol *symtab[HASHTABSIZE];void syminit(void){	register int i,hv;	/* clear all entries in the symbol table */	memset(symtab, 0, sizeof(struct symbol *) * HASHTABSIZE);	/* load all the pre-defined symbols */	for(i=0; i<SINITSIZE; i++ ) {		hv = hash(sinit[i].name);		if( symtab[hv] )			sinit[i].next = symtab[hv];		symtab[hv] = &sinit[i];		sinit[i].next = NULL;	}}/* free all the memory allocated for the symbols */void freesym(void){	struct symbol *sym, *next;	int i;	for (i=0; i<HASHTABSIZE; i++) {		sym = symtab[i];		while (sym != NULL) {			if (sym->predefined) {				sym = sym->next;			} else {				if (sym->name) free(sym->name);				next = sym->next;				free(sym);				sym = next;			}		}	}}

⌨️ 快捷键说明

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