/* Intermediate Virtual Assembly Language abs86 */ interface operand { public R accept(absmvisitor lv); } // the visitor will allow us to print slightly different concrete syntax // note that absmvisitor can visit both operands and operations interface absmvisitor { public T visit(immediate x); public T visit(register x); public T visit(mem x); public T visit(memlabel x); public T visit(operation x); } class immediate implements operand { int kind = 0; // 0=int, 1=label, 2= jump or call label (no $) int val; String label; public immediate(int v) {val=v;} public immediate(String l) {label=l; kind = 1;} public immediate(String l, boolean b) {label=l; kind = 2;} public R accept(absmvisitor lv) { return lv.visit(this); } } class register implements operand { String rname; public register(String s) {rname=s;} public R accept(absmvisitor lv) { return lv.visit(this); } } // memory reference: offset(Base,Index,scale) // A simple reference of (%ebp) will just be new mem(new register("ebp"),0) class mem implements operand { register Base; // can be null register Index = null; // can also be null int scale = 4; int offset; public mem(register b, int f) // constructor only sets base+offset { Base=b; offset=f; } public R accept(absmvisitor lv) { return lv.visit(this); } } // special class for memory labels // a fresh label can be automatically generated using the static counter. // also encapsulates for STR0: .string "abc" with strconst class memlabel { String name; String strconst = null; // String constant public static int counter = 0; public memlabel(String n) { name=n+counter; } public memlabel(String n, boolean inc) { name=n+counter; if (inc) counter++; } public memlabel(String n, String c, boolean inc) { name="STR"+counter; strconst=c; if (inc) counter++; } public R accept(absmvisitor lv) {return lv.visit(this);} } /////////////// class for operations // in case of one operand opcodes, ONLY the SRC will be used class operation { memlabel label = null; // can just be a label String opcode; // "mov", "add", etc operand src; // source operand operand dst; // dst operand int numops; // number of operands public operation(String p, operand a, operand b) { opcode=p; src=a; dst = b; numops=2; } public operation(String p, operand a) { opcode=p; src=a; numops=1; } public operation(String p) { opcode=p; numops=0; } public operation(memlabel m) {label=m; numops=-1;} public R accept(absmvisitor lv) { return lv.visit(this); } } // operation ////////////////// concrete visitors ///////////////////// // prints 32 bit GNU x86 assembly instructions class x86 implements absmvisitor { // For 32bit x86 only: public static final register EAX = new register("eax"); public static final register EBX = new register("ebx"); public static final register ECX = new register("ecx"); public static final register EDX = new register("edx"); public static final register EDI = new register("edi"); public static final register ESP = new register("esp"); public static final register EBP = new register("ebp"); public static String equiv(String s) { if (s.equals("+")) return "add"; if (s.equals("-")) return "sub"; if (s.equals("*")) return "imul"; if (s.equals("/")) return "idiv"; // careful! if (s.equals("&")) return "and"; if (s.equals("|")) return "or"; if (s.equals("!")) return "not"; if (s.equals("<")) return "jl"; if (s.equals("<=")) return "jle"; if (s.equals(">")) return "jg"; if (s.equals(">=")) return "jge"; if (s.equals("==")) return "je"; if (s.equals("!=")) return "jne"; if (s.equals("0")) return "jz"; if (s.equals("!=0")) return "jnz"; // warning: not exhuastive return s; } public String visit(immediate x) { if (x.kind==0) return "$"+x.val; else if (x.kind==1) return "$"+x.label; else return x.label; } public String visit(register x) { return "%"+x.rname;} public String visit(mem x) { String s; if (x.offset==0) s="("+x.Base.accept(this); else s=x.offset+"("+x.Base.accept(this); if (x.Index!=null) s = s+","+x.Index.accept(this)+","+x.scale; s = s+")"; return s; } public String visit(memlabel x) { String s = x.name+":"; if (x.strconst!=null) s=s+"\t.string \""+x.strconst+"\""; else s=s+"\tnop"; s=s+"\n"; return s; } public String visit(operation x) { if (x.label!=null) return x.label.accept(this); String s = "\t"+x.opcode+" "; if (x.numops>0) s = s+x.src.accept(this); if (x.numops>1) s = s+", "+x.dst.accept(this); s = s+"\n"; return s; } } // x86 visitor