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

📄 pas.c

📁 PASCAL语言子集编译器
💻 C
📖 第 1 页 / 共 4 页
字号:
			}
		else
			{
			emitRC("mov",regstats[reg].reg,medline->opv1,";把被减数立即数赋给结果寄存器");
			}/*为结果寄存器赋被加数的值*/
		if(v2!=NULL)
			{
			if(v2->regstats==1)
				emitRR("sub",regstats[reg].reg,regstats[v2->regnum].reg,";把被减数和在寄存器中的减数相减");
			else
				emitRM("sub",regstats[reg].reg,v2->name,";把被减数和在存储器中的减数相减");
			}
		else
			{
			emitRC("sub",regstats[reg].reg,medline->opv2,";把被减数和减数立即数相减");
			}/*完成对减法的四元式编译。*/
		regstats[reg].alter=1;
		break;
	case '*':
		v1=lookup(medline->opv1);	
		v2=lookup(medline->opv2);
		re=lookup(medline->result);	
		/*以上三行是三个操作数在符号表中的定位*/
		if((regstats[0].stats==1)&&(regstats[0].varname[0]>='a')&&(regstats[0].varname[0]<='z')&&(regstats[0].alter==1))
			{
			emitRM("mov",regstats[0].varname,"AX",";为执行乘法指令而保存AX中的变量");
			temp=st_lookup(regstats[0].varname,HashTable);
			temp->regstats=0;
			}		
		if((regstats[3].stats==1)&&(regstats[3].varname[0]>='a')&&(regstats[0].varname[0]<='z')&&(regstats[0].alter==1))
			{
			emitRM("mov",regstats[3].varname,"DX",";为执行乘法指令而保存DX中的变量");
			temp=st_lookup(regstats[3].varname,HashTable);
			temp->regstats=0;
			}
		if(regstats[0].stats==0)
			{
				if(v1!=NULL)
				{
				if(v1->regstats==1)
					emitRR("mov",regstats[0].reg,regstats[v1->regnum].reg,";把在寄存器中的被乘数赋给AX寄存器");
				else
					emitRM("mov",regstats[0].reg,v1->name,";把在存储器中的被乘数赋给AX寄存器");
				}
				else
				{
					emitRC("mov",regstats[0].reg,medline->opv1,";把被乘数立即数赋给AX寄存器");
				}	
			if(v2!=NULL)
				{
				if(v2->regstats==1)
					emitTO("mul",regstats[v2->regnum].reg,";把被乘数和在寄存器中的乘数相乘");
				else
					emitTO("mul",v2->name,";把被乘数和在存储器中的乘数相乘");
				}
			else
				{
				reg=assign_1(medline->opv2);
				emitRC("mov",regstats[reg].reg,medline->opv2,";把乘数立即数读入寄存器");
				emitTO("mul",regstats[reg].reg,";把被乘数和乘数立即数相乘");
				}
			}
		else
			{
			if(strcmp(regstats[0].varname,v1->name)==0)
				{
				if(v2!=NULL)
					{
					if(v2->regstats==1)
						emitTO("mul",regstats[v2->regnum].reg,";把被乘数和在寄存器中的乘数相乘");
					else
						emitTO("mul",v2->name,";把被乘数和在储存器中的乘数相乘");
					}
				else
					{
					reg=assign_1(medline->opv2);
					emitRC("mov",regstats[reg].reg,medline->opv2,";把乘数立即数读入寄存器");
					emitTO("mul",regstats[reg].reg,";把被乘数和乘数立即数相乘");
					}/*第二变量和第一变量相乘*/
				}
			else if(strcmp(regstats[0].varname,v2->name)==0)
				{
				if(v1!=NULL)
					{
					if(v1->regstats==1)
						emitTO("mul",regstats[v1->regnum].reg,";把被乘数和在寄存器中的乘数相乘");
					else
						emitTO("mul",v1->name,";把被乘数和在储存器中的乘数相乘");
					}
				else
					{
					reg=assign_1(medline->opv1);
					emitRC("mov",regstats[reg].reg,medline->opv1,";把乘数立即数读入寄存器");
					emitTO("mul",regstats[reg].reg,";把被乘数和乘数立即数相乘");
					}/*第二变量和第一变量相乘*/
				}
			else
				{
				if(v1!=NULL)
					{
					if(v1->regstats==1)
						emitRR("mov",regstats[0].reg,regstats[v1->regnum].reg,";把在寄存器中的被乘数赋给AX寄存器");
					else
						emitRM("mov",regstats[0].reg,v1->name,";把在储存器中的被乘数赋给AX寄存器");
					}
				else
					emitRC("mov",regstats[0].reg,medline->opv1,"把被乘数立即数赋给AX寄存器");
				if(v2!=NULL)
					{
					if(v2->regstats==1)
						emitTO("mul",regstats[v2->regnum].reg,";把被乘数和在寄存器中的乘数相乘");
					else
						emitTO("mul",v2->name,";把被乘数和在储存器中的乘数相乘");
					}
				else
					{
					reg=assign_1(medline->opv2);
					emitRC("mov",regstats[reg].reg,medline->opv2,"把被乘数立即数读入寄存器");
					emitTO("mul",regstats[reg].reg,";把被乘数和乘数立即数相乘");
					}/*完成对乘法的四元式编译*/
				}
			}
		strcpy(regstats[0].varname,re->name);/*结果变量使用AX寄存器*/
		re->regstats=1;
		re->regnum=0;/*把AX寄存器改为结果变量使用*/
		regstats[0].stats=1;
		regstats[0].alter=1;
		regstats[3].stats=0;
		break;
	case '/':
		v1=lookup(medline->opv1);	
		v2=lookup(medline->opv2);
		re=lookup(medline->result);	
		/*以上三行是三个操作数在符号表中的定位*/
		if((regstats[0].stats==1)&&(regstats[0].varname[0]>='a')&&(regstats[0].varname[0]<='z')&&(regstats[0].alter==1))
			{
			emitRM("mov",regstats[0].varname,"AX",";为执行除法指令而保存AX中的变量");
			temp=st_lookup(regstats[0].varname,HashTable);
			temp->regstats=0;
			}		
		if((regstats[3].stats==1)&&(regstats[3].varname[0]>='a')&&(regstats[0].varname[0]<='z')&&(regstats[0].alter==1))
			{
			emitRM("mov",regstats[3].varname,"DX",";为执行除法指令而保存DX中的变量");
			temp=st_lookup(regstats[3].varname,HashTable);
			temp->regstats=0;
			}
		emitRC("mov",regstats[3].reg,"0",";执行除法指令前DX寄存器清零");
		if(regstats[0].stats==0)
			{
				if(v1!=NULL)
				{
				if(v1->regstats==1)
					emitRR("mov",regstats[0].reg,regstats[v1->regnum].reg,";把在寄存器中的被除数赋给AX寄存器");
				else
					emitRM("mov",regstats[0].reg,v1->name,";把在存储器中的被除数赋给AX寄存器");
				}
				else
				{
					emitRC("mov",regstats[0].reg,medline->opv1,";把被除数立即数赋给AX寄存器");
				}	
			if(v2!=NULL)
				{
				if(v2->regstats==1)
					emitTO("div",regstats[v2->regnum].reg,";把被除数和在寄存器中的除数相除");
				else
					emitTO("div",v2->name,";把被除数和在存储器中的除数相除");
				}
			else
				{
				reg=assign_1(medline->opv2);
				emitRC("mov",regstats[reg].reg,medline->opv2,";把除数立即数读入寄存器");
				emitTO("div",regstats[reg].reg,";把被除数和除数立即数相除");
				}
			}
		else
			{
			if(strcmp(regstats[0].varname,v1->name)==0)
				{
				if(v2!=NULL)
					{
					if(v2->regstats==1)
						emitTO("div",regstats[v2->regnum].reg,";把被除数和在寄存器中的除数相除");
					else
						emitTO("div",v2->name,";把被除数和在储存器中的除数相除");
					}
				else
					{
					reg=assign_1(medline->opv2);
					emitRC("mov",regstats[reg].reg,medline->opv2,";把除数立即数读入寄存器");
					emitTO("div",regstats[reg].reg,";把被除数和除数立即数相除");
					}/*第二变量和第一变量相除*/
				}
			else
				{
				if(v1!=NULL)
					{
					if(v1->regstats==1)
						emitRR("mov",regstats[0].reg,regstats[v1->regnum].reg,";把在寄存器中的被除数赋给AX寄存器");
					else
						emitRM("mov",regstats[0].reg,v1->name,";把在储存器中的被除数赋给AX寄存器");
					}
				else
					emitRC("mov",regstats[0].reg,medline->opv1,"把被除数立即数赋给AX寄存器");
				if(v2!=NULL)
					{
					if(v2->regstats==1)
						emitTO("div",regstats[v2->regnum].reg,";把被除数和在寄存器中的除数相除");
					else
						emitTO("mul",v2->name,";把被除数和在储存器中的除数相除");
					}
				else
					{
					reg=assign_1(medline->opv2);
					emitRC("mov",regstats[reg].reg,medline->opv2,"把被除数立即数读入寄存器");
					emitTO("div",regstats[reg].reg,";把被除数和除数立即数相乘");
					}/*完成对除法的四元式编译*/
				}
			}
		strcpy(regstats[0].varname,re->name);/*结果变量使用AX寄存器*/
		re->regstats=1;
		re->regnum=0;/*把AX寄存器改为结果变量使用*/
		regstats[0].stats=1;
		regstats[0].alter=1;
		regstats[3].stats=0;
		break;
	case ':':
		v1=lookup(medline->opv1);
		re=lookup(medline->result);
		/*以上两行是两个操作数爱符号表中的定位*/
		if(re->regstats==1)
			reg=re->regnum;
		else
			reg=assign(re);
		if(v1!=NULL)
			{
			if(v1->regstats==0)
				emitRM("mov",regstats[reg].reg,v1->name,";执行赋值语句,存储器中的值赋给结果变量");
			else
				emitRR("mov",regstats[reg].reg,regstats[v1->regnum].reg,";执行赋值语句,寄存器中的值赋给结果变量");
			}
		else
			{
			emitRC("mov",regstats[reg].reg,medline->opv1,";执行赋值语句,立即数值赋给结果变量");
			}/*为第一变量分配寄存器*/
		regstats[reg].alter=1;
		break;
	case 'j':
		switch(medline->op[1])
			{
			case '\0':
				emitJ("jmp",medline->result,";产生直接跳转指令");
				break;
			default:
				v1=lookup(medline->opv1);
				v2=lookup(medline->opv2);
				if(v1!=NULL)
					{
					if(v1->regstats==1)
						reg=v1->regnum;
					else
						{
						reg=assign(v1);
						emitRM("mov",regstats[reg].reg,v1->name,";把条件跳转指令的第一操作数读入寄存器");
						}
					}
				else
					{
					reg=assign_1(medline->opv1);
					emitRC("mov",regstats[reg].reg,medline->opv1,";把条件跳转指令的第一操作数立即数读入寄存器");
					}/*为第一变量分配寄存器*/
				if(v2!=NULL)
					{
					if(v2->regstats==1)
						emitRR("cmp",regstats[reg].reg,regstats[v2->regnum].reg,";把条件跳转指令的第一操作数和第二操作数相减");
					else
						emitRM("cmp",regstats[reg].reg,v2->name,";把条件跳转指令的第一操作数和第二操作数相减");
					}
				else
					emitRC("cmp",regstats[reg].reg,medline->opv2,";把条件跳转指令的第一操作数和第二操作数相减");
				/*以上从default:这行开始产生条件跳转指令的条件状态*/
				switch(medline->op[1])
					{
					case '=':
						emitJ("je",medline->result,";相等则跳转");
						break;
					case '<':
						switch(medline->op[2])
							{
							case '\0':
								emitJ("jl",medline->result,";小于则跳转");
								break;
							case '=':
								emitJ("jle",medline->result,";小于或等于则跳转");
								break;
							}
						break;
					case '>':
						switch(medline->op[2])
							{
							case '\0':
								emitJ("jg",medline->result,";大于则跳转");
								break;
							case '=':
								emitJ("jge",medline->result,";大于或等于则跳转");
								break;
							}
						break;
					}
				break;
			}
		break;
	}
}


void create_codeseg()
{
int j,m;
m1 l;
vr k;
l=m1_line;
strcpy(regstats[0].reg,"AX");
strcpy(regstats[1].reg,"BX");
strcpy(regstats[2].reg,"CX");
strcpy(regstats[3].reg,"DX");
m=l->line;
printf("\n正在生成汇编语言的代码段!………………");
for(;;)
	{
	if(l==NULL)
		{
		for(j=0;j<=3;j++)
			{
			if(regstats[j].stats==1)
				{
				if((regstats[j].varname[0]>='a')&&(regstats[j].varname[0]='z'))
					{
					if(regstats[j].alter==1)
						emitRM("mov",regstats[j].varname,regstats[j].reg,";在程序结束之前保存寄存器中已改变的变量");
					}
				}
			}
		fprintf(code,"%d:\n",m+1);
		break;
		}
	if(Block[(l->line+1)%100]==1)
		{
		for(j=0;j<=3;j++)
			{
			if(regstats[j].stats==1)
				{
				if((regstats[j].varname[0]>='a')&&(regstats[j].varname[0]='z')&&(l->op[0]=='j'))
					{
					if(regstats[j].alter==1)
						emitRM("mov",regstats[j].varname,regstats[j].reg,";在跳出基本块之前保存寄存器中已改变的变量");
					}
				}
			}
		}
	fprintf(code,"%d:\n",l->line);
	emit_code(l);/*对单条四元式进行编译,产生一条或多条汇编代码。*/
	if(Block[(l->line+1)%100]==1)
		{
		for(j=0;j<=3;j++)
			{
			if(regstats[j].stats==1)
				{
				k=lookup(regstats[j].varname);
				k->regstats=0;
				if((regstats[j].varname[0]>='a')&&(regstats[j].varname[0]='z')&&(l->op[0]!='j'))
					{
					if(regstats[j].alter==1)
						emitRM("mov",regstats[j].varname,regstats[j].reg,";在跳出基本块之前保存寄存器中已改变的变量");
					}
				}
			regstats[j].stats=0;
			regstats[j].alter=0;
			}
		}
	m=l->line;
	l=l->next;
	}
}

/*过程codegen产生汇编目标语言的初始化程序段,*/
/*并调用相应的函数产生程序的数据段和代码段,*/
/*字符串变量codefile为目标文件的文件名,*/
/*用于在在编译过程中作为注释在屏幕上打印出文件名。*/

void codegen(char *codefile)
{
printf("\n正在把四元式编译车工内汇编语言,保存到文件 %s!…………",codefile);
fprintf(code,";File:%s\n",codefile);
fprintf(code,";***********************************************\n",codefile);
fprintf(code,"data segment  ",codefile);
fprintf(code,";定义数据段\n",codefile);
/*下面的create_dataseg函数是建立数据段的主程序*/
create_dataseg();
fprintf(code,"data ends     ",codefile);
fprintf(code,";数据段定义结束\n",codefile);
fprintf(code,";***********************************************\n",codefile);
fprintf(code,"code segment ",codefile);
fprintf(code,";定义代码段\n",codefile);
fprintf(code,"main proc far ",codefile);
fprintf(code,";程序的执行部分\n",codefile);
fprintf(code,"			assume cs:code,ds:data\n",codefile);
fprintf(code,"start:\n",codefile);
fprintf(code,"			;为返回操作系统入栈\n",codefile);
fprintf(code,"push ds\n",codefile);
fprintf(code,"sub bx,bx\n",codefile);
fprintf(code,"push ds\n",codefile);
fprintf(code,"			;设置DS段为当前数据段\n",codefile);
fprintf(code,"mov bx,data\n",codefile);
fprintf(code,"mov ds,bx\n",codefile);

/*下面的create_codeseg函数是建立代码段的主程序。*/
create_codeseg();
fprintf(code,"ret\n",codefile);
fprintf(code,"main endp\n",codefile);
fprintf(code,"code ends   ",codefile);
fprintf(code,";代码段定义结束\n",codefile);
fprintf(code,";end start\n",codefile);
}
/************************主程序**********************************/

main()
 {
 char filename[20]="pas.med",*codefilename="pas.asm";
 cfile=fopen("pas.dat","r");
 mfile=fopen("pas.med","w");
 /*打开C语言源文件*/
 readch();
 /*从源文件读一个字符*/
 scan();
 /*词法分析*/
 disp1();
 disp3();
 stack[sp].pos=0;
 stack[sp].sy1=-1;
 /*初始化状态栈栈底*/
 stack1[sp1]=0;
 /*初始化状态栈栈底*/
 oth.sy1=-1;
 readnu();
 /*从二元式读一个字符*/
 lrparse();
 getch();
 /*四元式分析*/
 disp2();
 fclose(cfile);
 fclose(mfile);

 /*中间语言-》汇编*/
 source=fopen("pas.med","r");
 code=fopen("pas.asm","w");
 read_file(filename);
 buildsymtab();
 create_basicblock();
 codegen(codefilename);
 fclose(source);
 fclose(code);
 }




		




		
     



























	

⌨️ 快捷键说明

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