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

📄 asm.c

📁 window下的c编译器。
💻 C
📖 第 1 页 / 共 5 页
字号:
 * Assume InputPointer is at start of symbol name.
 * Advance InputPointer past symbol name.
 * Turn that character into a '\0', returning its former value.
 * This allows a string compare of the symbol name.
 * There will always be a char following symbol name, because all good
 * lines end in end-of-line.
 */
static char get_symbol_end()
{
	register char c;
	while (is_part_of_name(c = *InputPointer++));
	*--InputPointer = 0;
	return (c);
}
/*
 * We expect the following sanitation has already been done.
 * No comments, reduce a comment to a space.
 * Reduce a tab to a space unless it is 1st char of line.
 * All multiple tabs and spaces collapsed into 1 char. Tab only
 * legal if 1st char of line.
 * # line file statements converted to .line x;.file y; statements.
 * Escaped newlines at end of line: remove them but add as many newlines
 * to end of statement as you removed in the middle, to synch line numbers.
 */
#define BEFORE_STRING ("\n")
#define AFTER_STRING ("\0") /* bcopy of 0 chars might choke. */
#define BEFORE_SIZE (1)
#define AFTER_SIZE  (1)
static char *buffer_start;  /* -> 1st char of full buffer area. */
static char *partial_where; /* -> after last full line in buffer. */
static int partial_size;/* >=0. Number of chars in partial line in buffer. */
/* Because we need AFTER_STRING just after last full line, it clobbers 1st part of
   partial line. So we preserve 1st part of partial line here. */
static char save_source[AFTER_SIZE];
/* What is the largest size buffer that input_file_give_next_buffer()
could return to us? */
static int buffer_length;
/*
We must track the physical file and line number for error messages.
We also track a "logical" file and line number corresponding to lcc
source line numbers.
*/

static int physical_input_line;
static void InitAsmInput(void)
{
	buffer_length = BUFFER_SIZE;
	buffer_start = xmalloc((long) (BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE));
	bcopy(BEFORE_STRING, buffer_start, (int) BEFORE_SIZE);
	/* Line number things. */
	physical_input_line = 0;
	partial_size = 0;
}
static void SetObjFileName(char *filename)
{
	char *p;

	if (OutputFileName == NULL) {
		OutputFileName = xmalloc(256);
		p = strrchr(filename,'\\');
		if (p == NULL) p = filename;
		else p++;
		strcpy(OutputFileName,p);
		p = strrchr(OutputFileName,'.');
		if (p) *p = 0;
		strcat(OutputFileName,".obj");
	}
	if (!strcmp(OutputFileName,filename)) {
		InternalError(1114); /* input and output file names are the same? */
	}
}
static void bump_line_counters(void)
{
	++physical_input_line;
}

/* Nonzero if we've hit a 'bad error', and should not write an obj file,
   and exit with a nonzero error code */
static int bad_error = 0;
void InternalError(int err)
{
	if (err < 2000) {
		fprintf(stderr,StrTab[393],err);// <Internal error %d\t>
	}
	else if (err < 3000) {
		fprintf(stderr,StrTab[394],err);// <Internal error %d\t>
		bad_error++;
	}
	else if (err < 4000) {
		fprintf(stderr,StrTab[395],err);// <Warning %d\t>
	}
	printf("line %d\n",physical_input_line);
	if (err < 2000) exit(err);
}
void WriteError(void)
{
	fprintf(stderr,StrTab[396]);// <Write error. Disk Full?\n>
	exit(1);
}
/* obstack.c - subroutines used implicitly by object stack macros */
/* Determine default alignment.  */
struct fooalign {
	char x;
	double d;
};
#define DEFAULT_ALIGNMENT ((char *)&((struct fooalign *) 0)->d - (char *)0)
/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
   But in fact it might be less smart and round addresses to as much as
   DEFAULT_ROUNDING.  So we prepare for it to do that.  */
#define DEFAULT_ROUNDING 4
/* When we copy a long block of data, this is the unit to do it with. */
#ifndef COPYING_UNIT
#define COPYING_UNIT int
#endif
static void _obstack_begin(struct obstack * h, int size, int alignment, void *(*chunkfun) (int), void (*freefun) (void *))
{
	register struct _obstack_chunk *chunk;  /* points to new chunk */
	if (alignment == 0)
		alignment = DEFAULT_ALIGNMENT;
	if (size == 0) {
		/* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc. Use the
		values for range checking, because if range checking is off, the
		extra bytes won't be missed terribly, but if range checking is on
		and we used a larger request, a whole extra 4096 bytes would be
		allocated.

		These number are irrelevant to the new GNU malloc.  I suspect it is
		less sensitive to the size of the request.  */
		int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
					+ 4 + DEFAULT_ROUNDING - 1)
					& ~(DEFAULT_ROUNDING - 1));
		size = 4096 - extra;
	}
	h->chunkfun = (struct _obstack_chunk * (*) (int)) chunkfun;
	h->freefun = freefun;
	h->chunk_size = size;
	h->alignment_mask = alignment - 1;
	chunk = h->chunk = (*h->chunkfun) (h->chunk_size);
	h->next_free = h->object_base = chunk->contents;
	h->chunk_limit = chunk->limit
		= (char *) chunk + h->chunk_size;
	chunk->prev = 0;
}
/* Allocate a new current chunk for the obstack *H on the assumption that LENGTH
   bytes need to be added to the current object, or a new object of length LENGTH
   allocated. Copies any partial object from the end of the old chunk to the
   beginning of the new one.
*/
static void _obstack_newchunk(struct obstack * h, int length)
{
	register struct _obstack_chunk *old_chunk = h->chunk;
	register struct _obstack_chunk *new_chunk;
	register long new_size;
	register int obj_size = h->next_free - h->object_base;
	register int i;
	int already;
	/* Compute size for new chunk.  */
	new_size = (obj_size + length) + (obj_size >> 3) + 100;
	if (new_size < h->chunk_size)
		new_size = h->chunk_size;
	/* Allocate and initialize the new chunk.  */
	new_chunk = h->chunk = (*h->chunkfun) (new_size);
	new_chunk->prev = old_chunk;
	new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
	/* Move the existing object to the new chunk. Word at a time is fast and
	is safe if the object is sufficiently aligned.  */
	if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT) {
		for (i = obj_size / sizeof(COPYING_UNIT) - 1;
				i >= 0; i--)
			((COPYING_UNIT *) new_chunk->contents)[i]
				= ((COPYING_UNIT *) h->object_base)[i];
		/* We used to copy the odd few remaining bytes as one extra
		COPYING_UNIT, but that can cross a page boundary on a machine which
		does not do strict alignment for COPYING_UNITS.  */
		already = obj_size / sizeof(COPYING_UNIT) * sizeof(COPYING_UNIT);
	}
	else
		already = 0;
	/* Copy remaining bytes one by one.  */
	for (i = already; i < obj_size; i++)
		new_chunk->contents[i] = h->object_base[i];
	/* If the object just copied was the only data in OLD_CHUNK, free that
	chunk and remove it from the chain.  */
	if (h->object_base == old_chunk->contents) {
		new_chunk->prev = old_chunk->prev;
		(*h->freefun) (old_chunk);
	}
	h->object_base = new_chunk->contents;
	h->next_free = h->object_base + obj_size;
}
/*
 * In: a character.
 * Out: TRUE if this character ends a line.
 */
#define _ (0)
static const char is_end_of_line[256] = {
	_, _, _, _, _, _, _, _, _, _, 99, _, _, _, _, _,    /* @abcdefghijklmno */
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
	_, _, _, _, _, _, _, _, _, _, _, 99, _, _, _, _,    /* 0123456789:;<=>? */
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _  /* */
};
#undef _
static char *hash_insert(struct HASH_LIST * where, char *name, char *data)
{
	struct HASH_LIST *rvp, *result,**slots;
	register int h;
	register char *p = name;
	int len;

	for (h = 0; *p;)
		h = (h << 2) ^ *p++;
	h &= HASHSIZE-1;
	slots = (struct HASH_LIST **)where->Data;
	rvp = slots[h];
	len = p - name;
	while (rvp) {
		if (rvp->len == len && !strcmp(name, rvp->Name)) return(rvp->Name);
		rvp = rvp->Next;
	}
	rvp = slots[h];
	result = (struct HASH_LIST *)allocate(sizeof(struct HASH_LIST),4);
	result->Next = rvp;
	result->Name = name;
	result->len = len;
	slots[h] = result;
	result->Data = data;
	return ("");
}
static char *hash_find(struct HASH_LIST * w, char *n)
{
	register struct HASH_LIST *rvp;
	register int h;
	register char *p = n;

	for (h = 0; *p;)
		h = (h << 2) ^ *p++;
	rvp = ((struct HASH_LIST **)w->Data)[h & (HASHSIZE-1)];
	h = p - n;
	while (rvp) {
		if ((rvp->len == h) && !strcmp(n, rvp->Name)) return(rvp->Data);
		rvp = rvp->Next;
	}
	return (NULL);
}
static struct HASH_LIST *hash_new(void)
{
	struct HASH_LIST *r;
	r = (struct HASH_LIST *) allocate(sizeof(struct HASH_LIST),4);
	r->Name = xmalloc(1);
	r->Data = xmalloc((HASHSIZE+1)*sizeof(struct HASH_LIST *));
	return (r);
}
static void symbol_table_insert(symbolS *symbolP)
{
	struct HASH_LIST *rvp;
	struct HASH_LIST *result,**slots;
	register int h;
	register char *p = symbolP->Name;
	char *n = p;

	for (h = 0; *p;)
		h = (h << 2) ^ *p++;
	h &= HASHSIZE-1;
	slots = (struct HASH_LIST **)sy_hash->Data;
	rvp = slots[h];
	result = (struct HASH_LIST *) allocate(sizeof(struct HASH_LIST),4);
	result->Next = rvp;
	result->Name = n;
	result->len = p - n;
	result->Data = (char *)symbolP;
	slots[h] = result;
	return;
}
/* set up pseudo-op tables */
static struct hash_control *po_hash = NULL; /* use before set up: NULL->
						address error */
static symbolS *CurrentFunctionSymbol;

static char *input_buffer(char *inbuffer,int len)
{
	register char *limit;   /* -> just after last char of buffer. */
	if (partial_size) {
		bcopy(partial_where, buffer_start + BEFORE_SIZE, (int) partial_size);
		bcopy(save_source, buffer_start + BEFORE_SIZE, (int) AFTER_SIZE);
	}
	memcpy(buffer_start + BEFORE_SIZE + partial_size,inbuffer,len);
	limit = buffer_start + BEFORE_SIZE + partial_size + len;
	if (len) {
		register char *p;   /* Find last newline. */
		for (p = limit; *--p != '\n';) {
		}
		++p;
		if (p <= buffer_start + BEFORE_SIZE) {
			InternalError(1006);
		}
		partial_where = p;
		partial_size = limit - p;
		bcopy(partial_where, save_source, (int) AFTER_SIZE);
		bcopy(AFTER_STRING, partial_where, (int) AFTER_SIZE);
	}
	else {
		partial_where = 0;
		if (partial_size > 0) {
			InternalError(2070);
		}
	}
	return (partial_where);
}

/* AsmReadBuffer()
 * File has already been opened, and will be closed by our caller.
 * We read the file, putting things into a web that
 * represents what we have been reading.
 */
void AsmReadBuffer(char *buffer,int len)
{
	register char c;
	register char *s;   /* string of symbol, '\0' appended */
	pseudo_typeS *pop;

	buffer_limit = input_buffer(buffer,len);   /* We have
						another line to parse. */
	know(buffer_limit[-1] == '\n'); /* Must have a sentinel. */
	InputPointer = buffer_start + BEFORE_SIZE;
contin:
	while (InputPointer < buffer_limit) { /* We have more of this
						buffer to parse. */
		/* We now have InputPointer -> 1st char of next line. If
		InputPointer [-1] == '\n' then we just scanned another
		line: so bump line counters. */
		if (InputPointer[-1] == '\n') {
			bump_line_counters();
		}
		/* We are at the begining of a line, or similar place. We expect
			a well-formed assembler statement. A "symbol-name:" is a
			statement. */
		while ((c = *InputPointer++) == '\t' || c == ' ') {
			;
		}
		know(c != ' '); /* No further leading whitespace. */
		/* c is the 1st significant character. InputPointer points
			after that character. */
		if (c == '\n') {
			continue;
		}
		if (c == ';') {
			while (*InputPointer != '\n')
				InputPointer++;
				continue;
		}
		if (is_name_beginner(c)) {  /* want user-defined label or
						pseudo/opcode */
			s = --InputPointe

⌨️ 快捷键说明

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