📄 assembler.java.svn-base
字号:
package cn.edu.buaa.scse.liyi.compile.tools;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedList;
import java.util.Vector;
import cn.edu.buaa.scse.liyi.compile.types.*;
/**
*
* @author liyi
*/
public class Assembler
{
private Vector<Constant> global_const=null;
private Vector<String> global_var=null;
private LinkedList<Function> funcList=null;
private Vector<String> output=null; //汇编输出
private Function func=null; //当前函数
private int pcount=0; //参数计数
private String condition=null;
private Vector<String> strlist=null; //printf用字符串表
private int stc=0; //字符串计数
private String outputpath;
private String warn=null;
/**
* 汇编代码生成器构造方法
* @param global_const
* @param global_var
* @param funcList
* @param outputpath
*/
public Assembler(Vector<Constant> global_const,Vector<String> global_var,LinkedList<Function> funcList,String outputpath)
{
this.funcList=funcList;
this.global_const=global_const;
this.global_var=global_var;
this.output=new Vector<String>();
this.strlist=new Vector<String>();
this.outputpath=outputpath;
strlist.add("@_IO_DATA dword ?");
strlist.add("@_IO_STR byte \"%d\", 0");
strlist.add("@_NEWLINE byte 0dh,0ah,0");
}
public void setGlobal_const(Vector<Constant> global_const)
{
this.global_const=global_const;
}
public Vector<Constant> getGlobal_const()
{
return global_const;
}
public void setGlobal_var(Vector<String> global_var)
{
this.global_var=global_var;
}
public Vector<String> getGlobal_var()
{
return global_var;
}
public void setOutput(Vector<String> output)
{
this.output=output;
}
public Vector<String> getOutput()
{
return output;
}
public void setStrlist(Vector<String> strlist)
{
this.strlist=strlist;
}
public Vector<String> getStrlist()
{
return strlist;
}
public void setWarn(String warn)
{
this.warn=warn;
}
public String getWarn()
{
return warn;
}
/********************************************************************************************/
//给出该参数或变量的地址表示,若为全局变量则返回原字符串
private String findAddress(String ss)
{
Integer i;
i=func.getPmap().get(ss); //在参数表里找
if(i!=null)
{
return "[ebp + "+i+" ]";
}
i=func.getVmap().get(ss);
if(i!=null)
{ //再在变量表里找
return "[ebp - "+i+" ]";
}
if(ss.equals("@teax"))
{ //若取函数调用的返回值则译为eax
return "eax";
}
if((ss.charAt(0)>='0'&&ss.charAt(0)<='9')||ss.charAt(0)=='-')
{ //当为全局常量时返回原数字
return ss;
}
else
{
return "$"+ss; //当为全局变量时直接返回加$的字符串
}
}
public void generateCode()
{
FileWriter fw=null;
for(Function func:this.funcList)
{ //遍历所有函数
this.func=func; //ff存当前函数,以为后面方法调用从中获得数据
int space=(this.func.getVmap().size()+4)*4; //算出函数调用需要的保留区大小,存为space
output.add("@f"+func.getName()+":"); //写入汇编函数头
output.add("push ebp");
output.add("mov ebp,esp");
output.add("sub esp,"+space);
for(Quaternion quater:func.getQuaterList())
{ //遍历该函数的所有四元式
switch (quater.getOperator())
{ //根据四元式的操作符op,转入相应的方法去添加对应的汇编代码
case Yacc.ADD:
add(quater);
break;
case Yacc.SUB:
sub(quater);
break;
case Yacc.MUL:
mul(quater);
break;
case Yacc.DIV:
div(quater);
break;
case Yacc.MOV:
mov(quater);
break;
case Yacc.CALL:
call(quater);
break;
case Yacc.CMP:
cmp(quater);
break;
case Yacc.CONDITION:
condition(quater);
break;
case Yacc.J:
j(quater);
break;
case Yacc.JFALSE:
jfalse(quater);
break;
case Yacc.PRINTF:
print(quater);
break;
case Yacc.PUSHPARA:
pushpara(quater);
break;
case Yacc.RETURN:
ret(quater);
break;
case Yacc.SCANF:
scan(quater);
break;
case Yacc.STAMP:
stamp(quater);
break;
default:
break;
}
}
if(func.getQuaterList().getLast().getOperator()!=Yacc.RETURN)
{ //检查是否有返回语句,若没有自动添加,并向用户发出警告
warn="Warning:Return Missing!";
output.add("mov esp,ebp");
output.add("pop ebp");
output.add("ret");
}
}
if(!"main".equals(funcList.getLast().getName()))
{
warn="Warning: 找不到main函数!";
}
else if(funcList.getLast().getRetype()==-1)
{
warn="Warning: main函数的返回类型没有定义!";
}
File ofile=new File(outputpath); //汇编输出文件
try
{
ofile.createNewFile();
}
catch (IOException e)
{
e.printStackTrace();
}
try
{
fw=new FileWriter(ofile);
fw.write(".386\n");
fw.write(".MODEL FLAT\n");
fw.write("includelib msvcrt.lib\n");
fw.write("puts proto C\n");
fw.write("printf proto C\n");
fw.write("scanf proto C\n");
fw.write(".STACK 4096\n");
fw.write(".DATA\n");
for(String s:this.global_var)
{
fw.write("$"+s+" DWORD 0\n");
}
for(String s:strlist)
{
fw.write(s+'\n');
}
fw.write(".CODE\n");
for(String s:output)
{
fw.write(s+'\n');
}
fw.write("_main:\n");
fw.write("jmp near ptr @fmain\n");
fw.write("end _main\n");
fw.flush();
fw.close();
}
catch(FileNotFoundException e)
{
e.printStackTrace();
}
catch(IOException e)
{
e.printStackTrace();
}
}
/**
* 加法操作
* @param quater
*/
private void add(Quaternion quater)
{
output.add("mov eax, "+findAddress(quater.getOperend1()));
output.add("add eax, "+findAddress(quater.getOperend2()));
output.add("mov "+findAddress(quater.getResult())+", eax");
}
/**
* 函数调用操作
* @param quater
*/
private void call(Quaternion quater)
{
output.add("call "+"@f"+quater.getOperend1());
output.add("add esp, "+(pcount*4));
pcount=0;
}
/**
* 比较操作
* @param quater
*/
private void cmp(Quaternion quater)
{
output.add("mov eax, "+findAddress(quater.getOperend1()));
output.add("cmp eax, "+findAddress(quater.getOperend2()));
}
/**
* 将应满足的条件存入condition字段,使后面的跳转语句可以确定其条件
* @param quater
*/
private void condition(Quaternion quater)
{
condition=quater.getOperend1();
}
/**
* 除法操作
* @param quater
*/
private void div(Quaternion quater)
{
output.add("mov eax, "+findAddress(quater.getOperend1()));
output.add("cdq");
output.add("mov ecx, "+findAddress(quater.getOperend2()));
output.add("idiv ecx");
output.add("mov "+findAddress(quater.getResult())+", eax");
}
/**
* 无条件跳转操作
* @param quater
*/
private void j(Quaternion quater)
{
output.add("jmp near ptr @l"+quater.getOperend1());
}
/**
* 不满足条件时的跳转操作
* @param quater
*/
private void jfalse(Quaternion quater)
{
switch(new Integer(condition).intValue())
{
case Lex.EE:
output.add("jne near ptr @l"+quater.getOperend1());
break;
case Lex.NE:
output.add("je near ptr @l"+quater.getOperend1());
break;
case Lex.G:
output.add("jle near ptr @l"+quater.getOperend1());
break;
case Lex.L:
output.add("jge near ptr @l"+quater.getOperend1());
break;
case Lex.GE:
output.add("jl near ptr @l"+quater.getOperend1());
break;
case Lex.LE:
output.add("jg near ptr @l"+quater.getOperend1());
break;
}
condition=null;
}
/**
* 赋值操作
* @param quater
*/
private void mov(Quaternion quater)
{
output.add("mov eax, "+findAddress(quater.getOperend1()));
output.add("mov "+findAddress(quater.getResult())+", eax");
}
/**
* 乘法操作
* @param quater
*/
private void mul(Quaternion quater)
{
output.add("mov eax, "+findAddress(quater.getOperend1()));
output.add("mov ecx, "+findAddress(quater.getOperend2()));
output.add("imul ecx");
output.add("mov "+findAddress(quater.getResult())+", eax");
}
/**
* 打印操作
* @param quater
*/
private void print(Quaternion quater)
{
String strname="@str"+stc;
switch (new Integer(quater.getResult()))
{
case 0:
// string
strlist.add(strname+" byte "+quater.getOperend1()+",0");
stc++;
output.add("lea eax, "+strname);
output.add("push eax");
output.add("call puts");
output.add("add esp, 4");
break;
case 1:
// integer
output.add("mov eax,"+findAddress(quater.getOperend2()));
output.add("push eax");
output.add("lea eax, @_IO_STR");
output.add("push eax");
output.add("call printf");
output.add("add esp, 8");
break;
case 2:
// both
/*
st.add(strname+" BYTE "+four.first+",0");
stc++;
output.add("mov eax,"+findAddress(four.last));
output.add("push eax");
output.add("lea eax, "+strname);
output.add("push eax");
output.add("call printf");
output.add("add esp, 8");
*/
strlist.add(strname+" BYTE "+quater.getOperend1()+",0");
stc++;
output.add("lea eax, "+strname);
output.add("push eax");
output.add("call puts");
output.add("add esp, 4");
output.add("mov eax, "+findAddress(quater.getOperend2()));
output.add("push eax");
output.add("lea eax, @_IO_STR");
output.add("push eax");
output.add("call printf");
output.add("add esp, 8");
break;
}
output.add("lea eax,@_NEWLINE");
output.add("push eax");
output.add("call printf");
output.add("add esp, 4");
}
/**
* 将参数压入运行栈操作
* @param quater
*/
private void pushpara(Quaternion quater)
{
output.add("push "+findAddress(quater.getOperend1()));
pcount++;
}
/**
* 返回操作
* @param quater
*/
private void ret(Quaternion quater)
{
if (quater.getOperend1() != null)
{
output.add("mov eax, "+findAddress(quater.getOperend1()));
}
output.add("mov esp,ebp");
output.add("pop ebp");
output.add("ret");
}
/**
* 读取操作
* @param quater
*/
private void scan(Quaternion quater)
{
output.add("lea eax, @_IO_DATA");
output.add("push eax");
output.add("lea eax, @_IO_STR");
output.add("push eax");
output.add("call scanf");
output.add("add esp, 8");
output.add("mov eax, @_IO_DATA");
output.add("mov "+findAddress(quater.getOperend1())+", eax");
}
/**
* 标签
* @param quater
*/
private void stamp(Quaternion quater)
{
output.add("@l"+quater.getOperend1()+" :");
}
/**
* 减法操作
* @param quater
*/
private void sub(Quaternion quater)
{
output.add("mov eax, "+findAddress(quater.getOperend1()));
output.add("sub eax, "+findAddress(quater.getOperend2()));
output.add("mov "+findAddress(quater.getResult())+", eax");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -