📄 generate.java.svn-base
字号:
package cn.edu.buaa.scse.liyi.test;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedList;
import java.util.Vector;
/**
*
* @author liyi
*/
public class Generate
{
private Vector<Constpair> topconst=null;
public Vector<String> topvar=null;
private LinkedList<Function> funclist=null;
public Vector<String> assembler=null; //汇编输出
private Function ff=null; //当前函数
private int pcount=0; //参数计数
private String condition=null;
public Vector<String> st=null; //printf用字符串表
private int stc=0; //字符串计数
private String path;
public String warn=null;
public Generate(Vector<Constpair> topconst,Vector<String> topvar,LinkedList<Function> funclist,String path)
{
this.funclist=funclist;
this.topconst=topconst;
this.topvar=topvar;
this.assembler=new Vector<String>();
this.st=new Vector<String>();
this.path=path;
st.add("@_IO_DATA dword ?");
st.add("@_IO_STR byte \"%d\", 0");
st.add("@_NEWLINE byte 0dh,0ah,0");
}
//给出该参数或变量的地址表示,若为全局变量则返回原字符串
private String findadr(String ss)
{
Integer i;
i=ff.pmap.get(ss); //在参数表里找
if(i!=null)
{
return "[ebp + "+i+" ]";
}
i=ff.vmap.get(ss);
if(i!=null)
{ //再在变量表里找
return "[ebp - "+i+" ]";
}
if(ss.equals("@teax"))
{ //若去函数调用的返回值怎译为eax
return "eax";
}
if(ss.charAt(0)>='0'&&ss.charAt(0)<='9')
{ //当为全局常量时返回原数字
return ss;
}
else
{
return "$"+ss; //当为全局变量时直接返回加$的字符串
}
}
public void Generate()
{
FileWriter fw=null;
for (Function func:this.funclist)
{ //遍历所有函数
ff=func; //ff存当前函数,以为后面方法调用从中获得数据
int space=(ff.vmap.size()+4)*4; //算出函数调用需要的保留区大小,存为space
assembler.add("@f"+func.name+":"); //写入汇编函数头
assembler.add("push ebp");
assembler.add("mov ebp,esp");
assembler.add("sub esp,"+space);
for (Quadruple quadruple:func.fourlist)
{ //遍历该函数的所有四元式
switch (quadruple.op)
{ //根据四元式的操作符op,转入相应的方法去添加对应的汇编代码
case Compile.ADD:
add(quadruple);
break;
case Compile.SUB:
sub(quadruple);
break;
case Compile.MUL:
mul(quadruple);
break;
case Compile.DIV:
div(quadruple);
break;
case Compile.MOV:
mov(quadruple);
break;
case Compile.CALL:
call(quadruple);
break;
case Compile.CMP:
cmp(quadruple);
break;
case Compile.CONDITION:
condition(quadruple);
break;
case Compile.J:
j(quadruple);
break;
case Compile.JFALSE:
jfalse(quadruple);
break;
case Compile.PRINTF:
print(quadruple);
break;
case Compile.PUSHPARA:
pushpara(quadruple);
break;
case Compile.RETURN:
ret(quadruple);
break;
case Compile.SCANF:
scan(quadruple);
break;
case Compile.STAMP:
stamp(quadruple);
break;
}
}
if (func.fourlist.getLast().op!=Compile.RETURN)
{ //检查是否有返回语句,若没有自动添加,并向用户发出警告
warn="Warning:Return Missing!";
assembler.add("mov esp,ebp");
assembler.add("pop ebp");
assembler.add("ret");
}
}
File ofile=new File(path); //汇编输出文件
try
{
ofile.createNewFile();
}
catch (IOException exc)
{
}
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.topvar)
{
fw.write("$"+s+" DWORD 0\n");
}
for(String s:st)
{
fw.write(s+'\n');
}
fw.write(".CODE\n");
for(String s:assembler)
{
fw.write(s+'\n');
}
fw.write("_main:\n");
fw.write("jmp near ptr @fmain\n");
fw.write("end _main\n");
fw.flush();
}
catch(FileNotFoundException ex)
{
}
catch(IOException ex)
{
}
}
//加法操作
private void add(Quadruple quadruple)
{
assembler.add("mov eax, "+findadr(quadruple.first));
assembler.add("add eax, "+findadr(quadruple.last));
assembler.add("mov "+findadr(quadruple.result)+", eax");
}
//函数调用操作
private void call(Quadruple quadruple)
{
assembler.add("call "+"@f"+quadruple.first);
assembler.add("add esp, "+(pcount*4));
pcount=0;
}
//比较操作
private void cmp(Quadruple quadruple)
{
assembler.add("mov eax, "+findadr(quadruple.first));
assembler.add("cmp eax, "+findadr(quadruple.last));
}
//把应满足的条件存入condition字段,使后面的跳转语句可以确定其条件
private void condition(Quadruple quadruple)
{
condition=quadruple.first;
}
//除法操作
private void div(Quadruple quadruple)
{
assembler.add("mov eax, "+findadr(quadruple.first));
assembler.add("cdq");
assembler.add("mov ecx, "+findadr(quadruple.last));
assembler.add("idiv ecx");
assembler.add("mov "+findadr(quadruple.result)+", eax");
}
//无条件跳转操作
private void j(Quadruple quadruple)
{
assembler.add("jmp near ptr @l"+quadruple.first);
}
//当不满足condition时跳转的操作
private void jfalse(Quadruple quadruple)
{
switch(new Integer(condition).intValue())
{
case Lex.EE:
assembler.add("jne near ptr @l"+quadruple.first);
break;
case Lex.NE:
assembler.add("je near ptr @l"+quadruple.first);
break;
case Lex.G:
assembler.add("jle near ptr @l"+quadruple.first);
break;
case Lex.L:
assembler.add("jge near ptr @l"+quadruple.first);
break;
case Lex.GE:
assembler.add("jl near ptr @l"+quadruple.first);
break;
case Lex.LE:
assembler.add("jg near ptr @l"+quadruple.first);
break;
}
condition=null;
}
//赋值操作
private void mov(Quadruple quadruple)
{
assembler.add("mov eax, "+findadr(quadruple.first));
assembler.add("mov "+findadr(quadruple.result)+", eax");
}
//乘法操作
private void mul(Quadruple quadruple)
{
assembler.add("mov eax, "+findadr(quadruple.first));
assembler.add("mov ecx, "+findadr(quadruple.last));
assembler.add("imul ecx");
assembler.add("mov "+findadr(quadruple.result)+", eax");
}
//打印操作
private void print(Quadruple quadruple)
{
String strname="@str"+stc;
switch (new Integer(quadruple.result))
{
case 0:
// string
st.add(strname+" byte "+quadruple.first+",0");
stc++;
assembler.add("lea eax, "+strname);
assembler.add("push eax");
assembler.add("call puts");
assembler.add("add esp, 4");
break;
case 1:
// integer
assembler.add("mov eax,"+findadr(quadruple.last));
assembler.add("push eax");
assembler.add("lea eax, @_IO_STR");
assembler.add("push eax");
assembler.add("call printf");
assembler.add("add esp, 8");
break;
case 2:
// both
/*
st.add(strname+" BYTE "+four.first+",0");
stc++;
assembler.add("mov eax,"+findadr(four.last));
assembler.add("push eax");
assembler.add("lea eax, "+strname);
assembler.add("push eax");
assembler.add("call printf");
assembler.add("add esp, 8");
*/
st.add(strname+" BYTE "+quadruple.first+",0");
stc++;
assembler.add("lea eax, "+strname);
assembler.add("push eax");
assembler.add("call puts");
assembler.add("add esp, 4");
assembler.add("mov eax, "+findadr(quadruple.last));
assembler.add("push eax");
assembler.add("lea eax, @_IO_STR");
assembler.add("push eax");
assembler.add("call printf");
assembler.add("add esp, 8");
break;
}
assembler.add("lea eax,@_NEWLINE");
assembler.add("push eax");
assembler.add("call printf");
assembler.add("add esp, 4");
}
//推参数操作
private void pushpara(Quadruple quadruple)
{
assembler.add("push "+findadr(quadruple.first));
pcount++;
}
//返回操作
private void ret(Quadruple quadruple)
{
if (quadruple.first != null)
{
assembler.add("mov eax, "+findadr(quadruple.first));
}
assembler.add("mov esp,ebp");
assembler.add("pop ebp");
assembler.add("ret");
}
//读取操作
private void scan(Quadruple quadruple)
{
assembler.add("lea eax, @_IO_DATA");
assembler.add("push eax");
assembler.add("lea eax, @_IO_STR");
assembler.add("push eax");
assembler.add("call scanf");
assembler.add("add esp, 8");
assembler.add("mov eax, @_IO_DATA");
assembler.add("mov "+findadr(quadruple.first)+", eax");
}
//标签
private void stamp(Quadruple quadruple)
{
assembler.add("@l"+quadruple.first+" :");
}
//减法操作
private void sub(Quadruple quadruple)
{
assembler.add("mov eax, "+findadr(quadruple.first));
assembler.add("sub eax, "+findadr(quadruple.last));
assembler.add("mov "+findadr(quadruple.result)+", eax");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -