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

📄 c2asm.cpp

📁 将C语言转换成汇编语言
💻 CPP
📖 第 1 页 / 共 5 页
字号:
}

void t(expr &p)
{
	if(input.clas=="parenthesis_open" || input.clas=="id" || input.clas=="int_const" || 
		input.clas=="long_const" )
	{
		expr p1;
		u(p1);
		add(p1,p);
	}
	else reject();
}

void add(expr p,expr &q)
{
	if(input.clas=="add_sub"
		&& input.index==15)
	{
		advanc();
		expr q1;
		u(q1);
		if(chk_types(p,q1)==true)
		{
		expr r1=newtemp(p.datatype);
		setatom(15,p,q1,r1);
		add(r1,q);
		}
		else
		{
		cout<<"\nFailed in <Add>--->"<< p.index<<" is different from "<<q1.index;
		reject();
		}
	}
	else if(input.clas=="add_sub" || input.clas=="relop" || input.clas=="parenthesis_close" || input.clas=="semicolon" || 
		input.clas=="comma")
	{
		q=p;
	}
	else reject();
}

void u(expr &p)
{
	if(input.clas=="parenthesis_open" || input.clas=="id" || input.clas=="int_const" ||
			input.clas=="long_const" )
	{
		expr p1;
		v(p1);
		multiply(p1,p);
	}
	else reject();
}

void multiply(expr p,expr &q)
{
	if(input.clas=="mul_div_mod"
		&& input.index==17 )
	{
		advanc();
		expr q1;
		v(q1);
		if(chk_types(p,q1)==true)
		{
		expr r1=newtemp(p.datatype);
		setatom(17,p,q1,r1);
		multiply(r1,q);
		}
		else
		{
		cout<<"\nFailed in <Multiply>--->"<<p.index<<" is different from "<<q1.index;
		reject();
		}
	}
	else if(input.clas=="add_sub" || input.clas=="add_sub" || input.clas=="relop" || input.clas=="parenthesis_close" || 
		input.clas=="semicolon" || input.clas=="comma" )
	{
		q=p;
	}
	else reject();
}

void v(expr &p)
{
	if(input.clas=="parenthesis_open" || input.clas=="id" || input.clas=="int_const" || input.clas=="long_const") 
	{
		expr p1;
		w(p1);
		divide(p1,p);
	}
	else reject();
}

void divide(expr p,expr &q)
{
	if(input.clas=="mul_div_mod"
		&& input.index==18)
	{
		advanc();
		expr q1;
		w(q1);
		if(chk_types(p,q1)==true)
		{
		expr r1=newtemp(p.datatype);
		setatom(18,p,q1,r1);
		divide(r1,q);
		}
		else
		{
		cout<<"\nFailed in <Divide>--->"<<p.index<<" is different from "<<q1.index;
		reject();
		}
	}
	else if(input.clas=="mul_div_mod" || input.clas=="add_sub" || input.clas=="add_sub" || input.clas=="relop" || 
		input.clas=="parenthesis_close" || input.clas=="semicolon" || input.clas=="comma")
	{
	q=p;
	}
	else reject();
}

void w(expr &p)
{
	if(input.clas=="parenthesis_open" || input.clas=="id" || input.clas=="int_const" || input.clas=="long_const")
	{
		expr p1;
		x(p1);
		mod(p1,p);
	}
	else reject();
	        
}

void mod(expr p,expr &q)
{
	if(input.clas=="mul_div_mod"
		&& input.index==19)
	{
		advanc();
		expr q1;
		x(q1);
		if(chk_types(p,q1)==true)
		{
		expr r1=newtemp(p.datatype);
		setatom(19,p,q1,r1);
		mod(r1,q);
		}
		else
		{
		cout<<"\nFailed in <Mod>---> "<< p.index<<"is different from "<< q1.index;
		reject();
		}
	}
	else if(input.clas=="mul_div_mod" || input.clas=="mul_div_mod" || input.clas=="add_sub" || input.clas=="add_sub" || 
		input.clas=="relop" || input.clas=="parenthesis_close" || input.clas=="semicolon" || input.clas=="comma")
	{
		q=p;
	}
	else reject();
}

void x(expr &p)
{
	if(input.clas=="parenthesis_open")
	{
		advanc();
		expression(p);
		if(input.clas=="parenthesis_close")
			advanc();
		else reject();
	}
	else if(input.clas=="id")
	{	
		long indx=chk_ident(input.index);
		if(indx!=-10) 
		{
			p.index=indx;
			p.whichtable=table;
			if(table==0)
			p.datatype=syn_identifier[indx].datatype;
			else if(table==1)
			p.datatype=args_identifier[indx].datatype;
		}
		else
		{
			cout<<"\nFailed in <X>-->...."
				<<" Variable "<<lex_identifier[input.index]<<" Not Found ";
			reject();
		}
		advanc();
	}
	else if(input.clas=="int_const")
	{
		p.datatype=23;
		p.index=input.index;
		p.whichtable=3;

		advanc();
	}
	else if(input.clas=="long_const")
	{
		p.datatype=24;
		p.index=input.index;
		p.whichtable=2;
		advanc();
	}
	else reject();
}

///**********************///
///**********************///
///						 ///
///   CODE GENERATOR	 ///
///		 STARTED		 ///	
///**********************///
///**********************///


//
//Code Generator's Globals
//
ofstream code(FILE_WRITE);
//ofstream code("C2ASM.txt");
bool collect_ebx=false;

///////////////////////////////////////////////
//
//Code Generator's Helper Fucntion Declarations
//
///////////////////////////////////////////////

//Used to ATTACH "g" to Global Variables.So,that they don't CLASH with Main()'s variables,Since
//I used to PUT all the Global And Main() Variables in .Data Segment of Assembly
void mangle_globals();

//If a Variable Appears inside some User Defined Function.It must be addressed by using [BP+..]
//In Short These and other situations,Where Name_Resolving is IMPORTANT this Function is called
string name_resolve(expr& e);

//It places All Global/Main() Variables in the Data Segment of Assembly Code.
void putvariables();

//It Converts a Long Number into String Object
string number2string(long count);

//It returns correct Jump condition for a Particular Relational Operator.
//Used By "CMP" ATOM only
string jcond4cmps(int& indx);

//It returns correct Jump condition for a Particular Relational Operator.
//Used By "JUMPF" ATOM only
string jcond4jumpf(int& indx);

//Following Functions are respective Mappings of ATOMS into Functions.
//Each of them get Called whenever ATOM of their respective type is seen.

void proc_marker(atom& atm);
void adds(atom& atm);
void assign(atom& atm);
void subs(atom& atm);
void mul(atom& atm);
void divs(atom& atm);
void label(atom& atm);
void jump(atom& atm);
void cmps(atom& atm);
void condjump(atom& atm);
void jumpf(atom& atm);
void call(atom& atm);
void param(atom& atm);
void returns(atom& atm);

//
//Code Generator's Helper Fucntion Definitions
//
void mangle_globals()
{
	for(unsigned int i=0;i<syn_identifier.size();i++)
		//Find only GLOBAL VARIABLES
		if(syn_identifier[i].binding==-2 &&
			syn_identifier[i].func_or_not==false)
		{
			syn_identifier[i].name="g"+syn_identifier[i].name;
		}
}

void putvariables()
{
	for(unsigned int i=0;i<syn_identifier.size();i++)
		//OUTPUT only GLOBAL AND MAIN VARIABLES + Temporaries
	if((syn_identifier[i].binding==-2 || syn_identifier[i].binding==-1)
		&& syn_identifier[i].func_or_not==false)
		{
		//Deciding Whether it's a LONG or an INTEGER?
		if(syn_identifier[i].datatype==0 ||syn_identifier[i].datatype==23)
		//An INTEGER
			code<<syn_identifier[i].name<<" dw "<<0<<endl;
		else
			//A LONG
			code<<syn_identifier[i].name<<" dd "<<0<<endl;
		}
}

void proc_marker(atom& atm)
{
	switch(atm.arg1.datatype)
	{
	
	//For Start Of Fucntion
	case 1:
		{
			switch(atm.arg1.index)
			{
				//It's main()
				case -1:
					code<<"main proc"<<endl
						<<"mov eax,@data"<<endl
						<<"mov ds,ax"<<endl;
					break;
				
				//It's an Ordinary Function
				default:
					code<<syn_identifier[atm.arg1.index].name
						<<" proc"<<endl
						<<"push bp"<<endl
						<<"mov bp,sp"<<endl
						<<"sub sp,"<<atm.arg1.whichtable<<endl;
			}
		}
		break;

	//For End Of Fucntion
	case 0:
		{
			switch(atm.arg1.index)
			{
				//It's main()
				case -1:
					code<<"mov ax,4c00h"<<endl
						<<"int 21h"<<endl
						<<"main endp"<<endl;
					break;
				
				//It's an Ordinary Function
				default:
					code<<"add sp,"<<atm.arg1.whichtable<<endl
						<<"pop bp"<<endl
						<<"ret"<<endl
						<<syn_identifier[atm.arg1.index].name
						<<" endp"<<endl;
			}
		}
		break;
	default:
		cout<<endl<<"Error in Fucntion Tagging";
		exit(-1);
	}

}

string name_resolve(expr& e)
{
	string name;
	switch(e.whichtable)
	{
	//Belongs to number_long
	case 2:
		name+=number2string(number_long[e.index]);
		break;

	//Belongs to number_int
	case 3:
		name+=number2string(number_int[e.index]);
		break;

	//Belongs to syn_identifier
	case 0:
		//If it Belongs to an Ordinary Fucntion
		if(syn_identifier[e.index].offset!=-10)
		{
			name+="[bp-";
			name+=number2string(syn_identifier[e.index].offset);
			name+="]";
		}
		//else it Belongs to a main() or a global variable
		else
			name=syn_identifier[e.index].name;	
		break;

		//Belongs to args_identifier
	case 1:
			name+="[bp+";
			name+=number2string(args_identifier[e.index].offset);
			name+="]";
			break;
	}
	return name;
}

string number2string(long count)
{	
	char name[40];
	char temp[40];

	ltoa(count,temp,10);
	strcpy(name,temp);

	return string(name);
}

void adds(atom& atm)
{
	//If its an INTEGER ADDITION use 16-Bit Registers
	if(atm.result.datatype==0)
	{
		code<<"push cx"<<endl
			<<"mov cx,0"<<endl
			<<"mov cx,word ptr "<<name_resolve(atm.arg1)<<endl
			<<"add cx,word ptr "<<name_resolve(atm.arg2)<<endl
			<<"mov "<<name_resolve(atm.result)<<",cx"<<endl
			<<"pop cx"<<endl;
	}
	//If its a LONG ADDITION use 32-Bit Registers
	else
	{
		code<<"push ecx"<<endl
			<<"mov ecx,0"<<endl
			<<"mov ecx,dword ptr "<<name_resolve(atm.arg1)<<endl
			<<"add ecx,dword ptr "<<name_resolve(atm.arg2)<<endl
			<<"mov "<<name_resolve(atm.result)<<",ecx"<<endl
			<<"pop ecx"<<endl;
	}
}
void assign(atom& atm)
{
	//If its an INTEGER ASSIGNMENT use 16-Bit Registers
	if(atm.result.datatype==0)
	{
		/*If The assignment is taking PLACE immediately after FUNCTION
		call,Then USE BX register from where data is to be copied*/
		if(collect_ebx==true)
		{
			code<<"mov "<<name_resolve(atm.result)<<",bx"<<endl;
			collect_ebx=false;
		}
		else
		{
		code<<"push cx"<<endl
			<<"mov cx,0"<<endl
			<<"mov cx,word ptr "<<name_resolve(atm.arg1)<<endl
			<<"mov "<<name_resolve(atm.result)<<",cx"<<endl
			<<"pop cx"<<endl;
		}
	}
	//If its a LONG ASSIGNMENT use 32-Bit Registers
	else
	{
		/*If The assignment is taking PLACE immediately after FUNCTION
		call,Then USE EBX register from where data is to be copied*/
		if(collect_ebx==true)
		{
			code<<"mov "<<name_resolve(atm.result)<<",ebx"<<endl;
			collect_ebx=false;
		}
		else
		{
		code<<"push ecx"<<endl
			<<"mov ecx,0"<<endl
			<<"mov ecx,dword ptr "<<name_resolve(atm.arg1)<<endl
			<<"mov "<<name_resolve(atm.result)<<",ecx"<<endl
			<<"pop ecx"<<endl;
		}
	}
}

void subs(atom& atm)
{
	//If its an INTEGER SUBTRACTION use 16-Bit Registers
	if(atm.result.datatype==0)
	{
		code<<"push cx"<<endl
			<<"mov cx,0"<<endl
			<<"mov cx,word ptr "<<name_resolve(atm.arg1)<<endl
			<<"sub cx,word ptr "<<name_resolve(atm.arg2)<<endl
			<<"mov "<<name_resolve(atm.result)<<",cx"<<endl
			<<"pop cx"<<endl;
	}
	//If its a LONG SUBTRACTION use 32-Bit Registers
	else
	{
		code<<"push ecx"<<endl
			<<"mov ecx,0"<<endl
			<<"mov ecx,dword ptr "<<name_resolve(atm.arg1)<<endl
			<<"sub ecx,dword ptr "<<name_resolve(atm.arg2)<<endl
			<<"mov "<<name_resolve(atm.result)<<",ecx"<<endl
			<<"pop ecx"<<endl;
	}
}

void mul(atom& atm)
{
	//If its an INTEGER MULTIPLICATION use 16-Bit Registers
	if(atm.result.datatype==0)
	{
	code<<"push cx"<<endl
		<<"mov cx,0"<<endl
		<<"mov cx,word ptr "<<name_resolve(atm.arg1)<<endl
		<<"mov "<<name_resolve(atm.result)<<",cx"<<endl
		<<"mov cx,"<<name_resolve(atm.arg2)<<endl
		<<"imul cx,word ptr "<<name_resolve(atm.result)<<endl
		<<"mov "<<name_resolve(atm.result)<<",cx"<<endl
		<<"pop cx"<<endl;
	}
	//If its a LONG MULTIPLICATION use 32-Bit Registers
	else
	{
	code<<"push ecx"<<endl
		<<"mov ecx,0"<<endl
		<<"mov ecx,dword ptr "<<name_resolve(atm.arg1)<<endl
		<<"mov "<<name_resolve(atm.result)<<",ecx"<<endl
		<<"mov ecx,dword ptr "<<name_resolve(atm.arg2)<<endl
		<<"imul ecx,"<<name_resolve(atm.result)<<endl
		<<"mov "<<name_resolve(atm.result)<<",ecx"<<endl
		<<"pop ecx"<<endl;
	}
}

void divs(atom& atm)
{
	//If its an INTEGER DIVISION use 16-Bit Registers
	if(atm.result.datatype==0)
	{
	code<<"push ax"<<endl
		<<"push cx"<<endl
		<<"push dx"<<endl
		<<"mov ax,0"<<endl
		<<"mov cx,0"<<endl
		<<"mov dx,0"<<endl
		<<"mov ax,word ptr "<<name_resolve(atm.arg1)<<endl
		<<"mov cx,word ptr "<<name_resolve(atm.arg2)<<endl
		<<"div cx"<<endl
		<<"mov "<<name_resolve(atm.result)<<",ax"<<endl
		<<"pop dx"<<endl
		<<"pop cx"<<endl
		<<"pop ax"<<endl;
	}
	//If its a LONG DIVISION use 32-Bit Registers
	else
	{
	code<<";Warning: Long Division is LOGICALLY FLAWED due to EAX"<<endl
		<<"push eax"<<endl
		<<"push ecx"<<endl
		<<"push edx"<<endl
		<<"mov eax,0"<<endl
		<<"mov ecx,0"<<endl
		<<"mov edx,0"<<endl
		<<"mov eax,dword ptr "<<name_resolve(atm.arg1)<<endl
		<<"mov ecx,dword ptr "<<name_resolve(atm.arg2)<<endl
		<<"div ecx"<<endl
		<<"mov "<<name_resolve(atm.result)<<",eax"<<endl
		<<"pop edx"<<endl
		<<"pop ecx"<<endl
		<<"pop eax"<<endl;
	}
}

void mods(atom& atm)
{
	//If its an INTEGER MOD use 16-Bit Registers
	if(atm.result.datatype==0)
	{
	code<<"push ax"<<endl
		<<"push cx"<<endl
		<<"push dx"<<endl
		<<"mov ax,0"<<endl
		<<"mov cx,0"<<endl
		<<"mov dx,0"<<endl
		<<"mov ax,word ptr "<<name_resolve(atm.arg1)<<endl
		

⌨️ 快捷键说明

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