📄 pas.c
字号:
}
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 + -