📄 generate.java
字号:
import java.io.File;import java.io.FileNotFoundException;import java.io.FileWriter;import java.io.IOException;import java.util.LinkedList;/* * To change this template, choose Tools | Templates * and open the template in the editor. */import java.util.Vector;/** * * @author lilac */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 (Four four : func.fourlist) { //遍历该函数的所有四元式 switch (four.op) { //根据四元式的操作符op,转入相应的方法去添加对应的汇编代码 case Compile.ADD: add(four); break; case Compile.SUB: sub(four); break; case Compile.MUL: mul(four); break; case Compile.DIV: div(four); break; case Compile.MOV: mov(four); break; case Compile.CALL: call(four); break; case Compile.CMP: cmp(four); break; case Compile.CONDITION: condition(four); break; case Compile.J: j(four); break; case Compile.JFALSE: jfalse(four); break; case Compile.PRINTF: print(four); break; case Compile.PUSHPARA: pushpara(four); break; case Compile.RETURN: ret(four); break; case Compile.SCANF: scan(four); break; case Compile.STAMP: stamp(four); 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(Four four) { assembler.add("mov eax, " + findadr(four.first)); assembler.add("add eax, " + findadr(four.last)); assembler.add("mov " + findadr(four.result) + ", eax"); }//函数调用操作 private void call(Four four) { assembler.add("call " + "@f" + four.first); assembler.add("add esp, " + (pcount * 4)); pcount = 0; }//比较操作 private void cmp(Four four) { assembler.add("mov eax, " + findadr(four.first)); assembler.add("cmp eax, " + findadr(four.last)); }//把应满足的条件存入condition字段,使后面的跳转语句可以确定其条件 private void condition(Four four) { condition = four.first; }//除法操作 private void div(Four four) { assembler.add("mov eax, " + findadr(four.first)); assembler.add("cdq"); assembler.add("mov ecx, " + findadr(four.last)); assembler.add("idiv ecx"); assembler.add("mov " + findadr(four.result) + ", eax"); }//无条件跳转操作 private void j(Four four) { assembler.add("jmp near ptr @l" + four.first); }//当不满足condition时跳转的操作 private void jfalse(Four four) { switch (new Integer(condition).intValue()) { case Lex.EE: assembler.add("jne near ptr @l" + four.first); break; case Lex.NE: assembler.add("je near ptr @l" + four.first); break; case Lex.G: assembler.add("jle near ptr @l" + four.first); break; case Lex.L: assembler.add("jge near ptr @l" + four.first); break; case Lex.GE: assembler.add("jl near ptr @l" + four.first); break; case Lex.LE: assembler.add("jg near ptr @l" + four.first); break; } condition = null; }//赋值操作 private void mov(Four four) { assembler.add("mov eax, " + findadr(four.first)); assembler.add("mov " + findadr(four.result) + ", eax"); }//乘法操作 private void mul(Four four) { assembler.add("mov eax, " + findadr(four.first)); assembler.add("mov ecx, " + findadr(four.last)); assembler.add("imul ecx"); assembler.add("mov " + findadr(four.result) + ", eax"); }//打印操作 private void print(Four four) { String strname = "@str" + stc; switch (new Integer(four.result)) { case 0: // string st.add(strname + " byte " + four.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(four.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 " + four.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(four.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(Four four) { assembler.add("push " + findadr(four.first)); pcount++; }//返回操作 private void ret(Four four) { if (four.first != null) { assembler.add("mov eax, " + findadr(four.first)); } assembler.add("mov esp,ebp"); assembler.add("pop ebp"); assembler.add("ret"); }//读取操作 private void scan(Four four) { 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(four.first) + ", eax"); }//标签 private void stamp(Four four) { assembler.add("@l" + four.first + " :"); }//减法操作 private void sub(Four four) { assembler.add("mov eax, " + findadr(four.first)); assembler.add("sub eax, " + findadr(four.last)); assembler.add("mov " + findadr(four.result) + ", eax"); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -