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

📄 gas2masm.c

📁 hl2 source code. Do not use it illegal.
💻 C
📖 第 1 页 / 共 2 页
字号:
void emit_1_or_2_operandsl_vartext (char *str0, char *str1)
{
	int		j;

	if (tokennum == 2)
	{
		printf (" %s ", str0);
		emitanoperand (1, "ds:dword ptr", 1);
	}
	else if (tokennum == 3)
	{
		if (!strcmpi (tokens[2], "%st(0)"))
			printf (" %s ", str0);
		else
			printf (" %s ", str1);

		emitanoperand (2, "ds:dword ptr", 1);
		printf (",");
		emitanoperand (1, "ds:dword ptr", 1);
	}
	else
	{

		fprintf (stderr, "Error: too many operands\n");

		for (j=0 ; j<tokennum ; j++)
			fprintf (stderr, "%s\n", tokens[j]);

		fprintf (stderr, "\n");
		errorexit ();
	}
}


void special_fdivl (void)
{

	emit_1_or_2_operandsl_vartext ("fdiv", "fdivr");
}


void special_fdivpl (void)
{

	emit_1_or_2_operandsl_vartext ("fdivp", "fdivrp");
}


void special_fdivrl (void)
{

	emit_1_or_2_operandsl_vartext ("fdivr", "fdiv");
}


void special_fdivrpl (void)
{

	emit_1_or_2_operandsl_vartext ("fdivrp", "fdivp");
}


void special_fsubl (void)
{

	emit_1_or_2_operandsl_vartext ("fsub", "fsubr");
}


void special_fsubpl (void)
{

	emit_1_or_2_operandsl_vartext ("fsubp", "fsubrp");
}


void special_fsubrl (void)
{

	emit_1_or_2_operandsl_vartext ("fsubr", "fsub");
}


void special_fsubrpl (void)
{

	emit_1_or_2_operandsl_vartext ("fsubrp", "fsubp");
}


void emit_multiple_data (void)
{
	int		i;

	printf (" ");

	for (i=1 ; i<(tokennum-1) ; i++)
	{
		emitanoperand (i, "", 0);
		printf (", ");
	}

	emitanoperand (i, "", 0);
}


//==============================================

parsefield	parsedata[] = {
	{".align", " align", 2, emitonedata},
	{".byte",  " db", -2, emit_multiple_data},
	{".data",  "", 1, datasegstart},
	{".extern"," externdef", 2, emitexterndef},
	{".globl", " public", -2, emit_multiple_data},
	{".long",  " dd", -2, emit_multiple_data},
	{".single"," dd", -2, emit_multiple_data},
	{".text",  "", 1, textsegstart},
	{"adcl",   " adc", 3, emittwooperandsl},
	{"addb",   " add", 3, emittwooperandsb},
	{"addl",   " add", 3, emittwooperandsl},
	{"andb",   " and", 3, emittwooperandsb},
	{"andl",   " and", 3, emittwooperandsl},
	{"call",   " call", 2, emitonecalldata},
	{"cmpb",   " cmp", 3, emittwooperandsb},
	{"cmpl",   " cmp", 3, emittwooperandsl},
	{"cmpw",   " cmp", 3, emittwooperandsw},
	{"decl",   " dec", 2, emitoneoperandl},
	{"decw",   " dec", 2, emitoneoperandw},
	{"divl",   " div", 2, emitoneoperandl},
	{"fadd",   " fadd", -2, emit_1_or_2_operandsl},
	{"faddp",  " faddp", -2, emit_1_or_2_operandsl},
	{"faddps", " faddp", -2, emit_1_or_2_operandsl},
	{"fadds",  " fadd", -2, emit_1_or_2_operandsl},
	{"fcom",   " fcom", 2, emitoneoperandl},
	{"fcoms",  " fcom", 2, emitoneoperandl},
	{"fcomp",  " fcomp", 2, emitoneoperandl},
	{"fcomps", " fcomp", 2, emitoneoperandl},
	{"fdiv",   "", -2, special_fdivl}, 
	{"fdivp",  "", -2, special_fdivpl}, 
	{"fdivr",  "", -2, special_fdivrl},
	{"fdivrp", "", -2, special_fdivrpl},
	{"fdivrs", "", -2, special_fdivrl},
	{"fildl",  " fild", 2, emitoneoperandl},
	{"fistl",  " fist", 2, emitoneoperandl},
	{"fistpl", " fistp", 2, emitoneoperandl},
	{"fld",    " fld", 2, emitoneoperandl},
	{"fldcw",  " fldcw", 2, emitoneoperandw},
	{"fldenv", " fldenv", 2, emitoneoperandl},
	{"flds",   " fld", 2, emitoneoperandl},
	{"fmul",   " fmul", -2, emit_1_or_2_operandsl},
	{"fmulp",  " fmulp", -2, emit_1_or_2_operandsl},
	{"fmulps", " fmulp", -2, emit_1_or_2_operandsl},
	{"fmuls",  " fmul", -2, emit_1_or_2_operandsl},
	{"fnstcw", " fnstcw", 2, emitoneoperandw},
	{"fnstenv"," fnstenv", 2, emitoneoperandl},
	{"fnstsw", " fnstsw", 2, emitoneoperandw},
	{"fstp",   " fstp", 2, emitoneoperandl},
	{"fstps",  " fstp", 2, emitoneoperandl},
	{"fsts",   " fst", 2, emitoneoperandl},
	{"fsubr",  "", -2, special_fsubrl},
	{"fsubrp", "", -2, special_fsubrpl},
	{"fsubrs", "", -2, special_fsubrl},
	{"fsub",   "", -2, special_fsubl},
	{"fsubp",  "", -2, special_fsubpl},
	{"fsubps", "", -2, special_fsubpl},
	{"fsubs",  "", -2, special_fsubl},
	{"fxch",   " fxch", 2, emitoneoperandl},
	{"imull",  " imul", -2, emit_1_or_2_operandsl},
	{"incl",   " inc", 2, emitoneoperandl},
	{"ja",     " ja", 2, emitonedata},
	{"jae",    " jae", 2, emitonedata},
	{"jb",     " jb", 2, emitonedata},
	{"jbe",    " jbe", 2, emitonedata},
	{"jc",     " jc", 2, emitonedata},
	{"je",     " je", 2, emitonedata},
	{"jg",     " jg", 2, emitonedata},
	{"jge",    " jge", 2, emitonedata},
	{"jl",     " jl", 2, emitonedata},
	{"jle",    " jle", 2, emitonedata},
	{"jmp",    " jmp", 2, emitonejumpdata},
	{"jna",    " jna", 2, emitonedata},
	{"jnae",   " jnae", 2, emitonedata},
	{"jnb",    " jnb", 2, emitonedata},
	{"jnbe",   " jnbe", 2, emitonedata},
	{"jnc",    " jnc", 2, emitonedata},
	{"jne",    " jne", 2, emitonedata},
	{"jng",    " jng", 2, emitonedata},
	{"jnge",   " jnge", 2, emitonedata},
	{"jnl",    " jnl", 2, emitonedata},
	{"jnle",   " jnle", 2, emitonedata},
	{"jns",    " jns", 2, emitonedata},
	{"jnz",    " jnz", 2, emitonedata},
	{"js",     " js", 2, emitonedata},
	{"jz",     " jz", 2, emitonedata},
	{"leal",   " lea", 3, emittwooperandsl},
	{"movb",   " mov", 3, emittwooperandsb},
	{"movl",   " mov", 3, emittwooperandsl},
	{"movw",   " mov", 3, emittwooperandsw},
	{"negl",   " neg", 2, emitoneoperandl},
	{"orb",    " or", 3, emittwooperandsb},
	{"orl",    " or", 3, emittwooperandsl},
	{"popl",   " pop", 2, emitoneoperandl},
	{"pushl",  " push", 2, emitoneoperandl},
	{"ret",    " ret", -1, emit_0_or_1_operandsl},
	{"rorl",   " ror", 3, emittwooperandsl},
	{"sarl",   " sar", 3, emittwooperandsl},
	{"sbbl",   " sbb", 3, emittwooperandsl},
	{"shll",   " shl", 3, emittwooperandsl},
	{"shrl",   " shr", 3, emittwooperandsl},	
	{"subl",   " sub", 3, emittwooperandsl},
	{"testb",  " test", 3, emittwooperandsb},
	{"testl",  " test", 3, emittwooperandsl},
	{"xorb",   " xor", 3, emittwooperandsb},
	{"xorl",   " xor", 3, emittwooperandsl},
};

int	numparse = sizeof (parsedata) / sizeof (parsedata[0]);

//==============================================

void errorexit (void)
{
	fprintf (stderr, "In line: %d, out line: %d\n", inline, outline);
	exit (1);
}


tokenstat whitespace (char c)
{
	if (c == '\n')
		return LINE_DONE;

	if ((c <= ' ') ||
		(c > 127) ||
		(c == ','))
	{
		return WHITESPACE;
	}

	return NOT_WHITESPACE;
}


int gettoken (void)
{
	char		c;
	int			count, parencount;
	tokenstat	stat;

	do
	{
		if ((c = getchar ()) == EOF)
			return FILE_DONE;

		if ((stat = whitespace (c)) == LINE_DONE)
			return LINE_DONE;
	} while (stat == WHITESPACE);

	token[0] = c;
	count = 1;

	if (c == '~')
	{
		count--;
		token[count++] = 'n';
		token[count++] = 'o';
		token[count++] = 't';
		token[count++] = ' ';
	}

	if (c == '(')
	{
		do
		{
			if ((c = getchar ()) == EOF)
			{
				fprintf (stderr, "EOF in middle of parentheses\n");
				errorexit ();
			}

			token[count++] = c;

		} while (c != ')');
	}
	
	for ( ;; )
	{
		if ((c = getchar ()) == EOF)
		{
			token[count] = 0;
			return TOKEN_AVAILABLE;
		}

		if (whitespace (c) == LINE_DONE)
		{
			if (ungetc (c, stdin) == EOF)
			{
				fprintf (stderr, "Couldn't unget character\n");
				errorexit ();
			}

			token[count] = 0;
			return TOKEN_AVAILABLE;
		}

		if (whitespace (c) == WHITESPACE)
		{
			token[count] = 0;
			return TOKEN_AVAILABLE;
		}

		if (count >= MAX_TOKEN_LENGTH)
		{
			fprintf (stderr, "Error: token too long\n");
			errorexit ();
		}

		token[count++] = c;

		if (c == '~')
		{
			count--;
			token[count++] = 'n';
			token[count++] = 'o';
			token[count++] = 't';
			token[count++] = ' ';
		}
		else if (c == '(')
		{
			parencount = 1;

			do
			{
				if ((c = getchar ()) == EOF)
				{
					fprintf (stderr, "EOF in middle of parentheses\n");
					errorexit ();
				}

				if (c == '(')
					parencount++;
				else if (c == ')')
					parencount--;

				if (c == '~')
				{
					token[count++] = 'n';
					token[count++] = 'o';
					token[count++] = 't';
					token[count++] = ' ';
				}
				else
				{
					token[count++] = c;
				}

			} while ((c != ')') || (parencount > 0));
		}
	}
}


tokenstat parseline (void)
{
	tokenstat	stat;
	int			i, j, firsttoken, labelfound;
	int			mnemfound;

	firsttoken = 1;
	tokennum = 0;
	labelfound = 0;

	for ( ;; )
	{
		token = tokens[tokennum];
		stat = gettoken ();

		switch (stat)
		{
		case FILE_DONE:
			return FILE_DONE;

		case LINE_DONE:
			if (!firsttoken && tokennum)
			{
				mnemfound = 0;

				for (i=0 ; i<numparse; i++)
				{
					if (!strcmpi (tokens[0], parsedata[i].text))
					{
						if (((parsedata[i].numtokens > 0) &&
							 (parsedata[i].numtokens != tokennum)) ||
							((parsedata[i].numtokens < 0) &&
							 (tokennum < -parsedata[i].numtokens)))
						{
							fprintf (stderr, "mismatched number of tokens\n");

							for (j=0 ; j<tokennum ; j++)
								fprintf (stderr, "%s\n", tokens[j]);

							fprintf (stderr, "\n");
							errorexit ();
						}

						printf ("%s", parsedata[i].emit);
						(*parsedata[i].parsefunc) ();

						mnemfound = 1;
						break;
					}
				}

				if (!mnemfound)
				{
					fprintf (stderr, "Error: unknown mnemonic\n");

					for (j=0 ; j<tokennum ; j++)
						fprintf (stderr, "%s\n", tokens[j]);

					fprintf (stderr, "\n");
					errorexit ();
				}
			}

			if (!firsttoken)
			{
				if ((currentseg == DATASEG) && labelfound && !tokennum)
					printf (":\n");
				else
					printf ("\n");

				outline++;
			}
			return PARSED_OKAY;

		case TOKEN_AVAILABLE:
			if (firsttoken)
			{
				if (token[strlen(token) - 1] == ':')
				{
					labelfound = 1;

					if (currentseg == DATASEG)
					{
						token[strlen(token) - 1] = 0;
						printf ("%s", token);
					}
					else if (currentseg == TEXTSEG)
					{
						printf ("%s", token);
					}
					else
					{
						fprintf (stderr, "Error: not in segment block\n");
						errorexit ();
					}

					firsttoken = 0;
					break;
				}
			}

			firsttoken = 0;

			if (tokennum >= MAX_TOKENS)
			{
				fprintf (stderr, "Error: too many tokens\n");
				exit (0);
			}

			tokennum++;

			break;

		default:
			fprintf (stderr, "Error: unknown tokenstat %d\n", stat);
			exit (0);
		}
	}
}


void main (int argc, char **argv)
{
	tokenstat	stat;

	printf (" .386P\n"
            " .model FLAT\n");
	inline = 1;
	outline = 3;

	for ( ;; )
	{
		stat = parseline ();
		inline++;

		switch (stat)
		{
		case FILE_DONE:
			if (currentseg == TEXTSEG)
				printf ("_TEXT ENDS\n");
			else if (currentseg == DATASEG)
				printf ("_DATA ENDS\n");

			printf (" END\n");
			exit (0);
		
		case PARSED_OKAY:
			break;

		default:
			fprintf (stderr, "Error: unknown tokenstat %d\n", stat);
			exit (0);
		}
	}
}

⌨️ 快捷键说明

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