📄 intel86.j4
字号:
if (OT_reg != OpType (dst)) { throw new InternalError ("x86: POP requires register operand: " + dst); } // We'll use the alternate encoding return encode (0x58 | ((Register)dst).getRegBitName ()); } /** Assemble a PUSH instruction */ public byte [] PUSH (Object dst) { // We'll use the alternate encoding for registers switch (OpType (dst)) { case OT_imm: return encode (makeByteArray (0x68 | valSFlag (dst)), null, makeByteArray ((Immediate) dst)); case OT_reg: return encode (0x50 | ((Register)dst).getRegBitName ()); case OT_mem: return encode (makeByteArray (0xff), makeModRM (0x06, dst), null); default: throw new InternalError ("x86: invalid operand " + dst + " for PUSH"); } } /** A one-byte instruction that does nothing. */ public byte [] NOP () { return encode (0x90); } /** A one-byte instruction we can use as a warning track to note when * code that should not be reached was, in fact, reached. We use the * Intel HLT instruction. */ public byte [] UNIMP (int x) // Parameter which might be encoded in the instruction { return encode (0xf4); } /** Assemble a TEST instruction */ public byte [] TEST (Object src, Object dst) { int sot = checkOperand (src); int dot = checkOperand (dst); if (OT_imm == sot) { Immediate imOp = (Immediate) src; if (OT_reg == dot) { Register rOp = (Register) dst; if (rOp.isAReg ()) { boolean byteOp; byteOp = rOp.is8BitReg (); return encode ( makeByteArray (0xa8 | (byteOp ? 0x00 : WFlag)), null, makeByteArray (imOp.setImmSize (byteOp ? 1 : 4))); } } int wFlag; wFlag = valWFlag (dst); return encode ( makeByteArray (0xf6 | wFlag), makeModRM (0, dst), makeByteArray (imOp.setImmSize ((0 == wFlag) ? 1 : 4))); } return encode (makeByteArray (0x84 | valWFlag (src, dst)), makeModRM (src, dst), null); } /** Backpatch a near jump. * @param boffs offset in code block of instruction following jump * @param dist how far the jump is (displacement to store) */ protected void PatchNearJump (int boffs, int dist) { if ((-128 > dist) || (127 < dist)) { throw new InternalError ("x86: Patch of " + dist + " invalid for near jump"); } /* Near unconditional jumps are EB disp8, and near conditional jumps * are 7t disp8. boffs is the offset of the instruction following * the jump. */ storeByte ((byte) dist, boffs - 1); return; } /** Backpatch a far-but-same-segment jump. * @param boffs offset in code block of instruction following jump * @param dist how far the jump is (displacement to store) */ protected void PatchLongJump (int boffs, int dist) { /* Long unconditional jumps are E9 disp32, and long conditional jumps * are 0F 8t disp32. boffs is the offset of the instruction following * the jump.. */ storeWord (dist, boffs - 4); return; } /** NB: Double-word values must be ordered the same in both the * stack and the local variables: i.e., if the high word is in * local i and the low in local i+1, then the high word * must be pushed onto the stack first, followed by the low * word. Otherwise word swapping occurs during parameter passing. * We maintain Intel ordering, and push MSW first, LSW second, so * LSW is below MSW in memory. */ /** pull the top word off the evaluation stack into a register * @param reg where value goes * @returns last code generated */ public byte [] popES (Object reg) { return MOV (relBPop (popEStackOffs()), reg); } /** pull the top double-word off the evaluation stack into a register * @param reg where value goes * @returns last code generated */ public byte [] LpopES (Object msreg, Object lsreg) { MOV (relBPop (popEStackOffs()), lsreg); return MOV (relBPop (popEStackOffs()), msreg); } /** pull the top word off the evaluation stack into a floating point register * @returns last code generated */ public byte [] FpopES () { return FLD (relBPop (popEStackOffs ()).setRefSize (4)); } /** pull the top double-word float off the evaluation stack into a register * @returns last code generated */ public byte [] DpopES () { byte instr []; instr = FLD (relBPop (popEStackOffs ()).setRefSize (8)); popEStackOffs (); return instr; } /** throw away the top n words of the evaluation stack * @param nw number of words to ditch * @returns code generated */ public byte [] tossES (int na) { tossEStackOffs (na); return new byte [0]; } /** push the value from the given register onto the evaluation stack * @param reg where value comes from * @returns code generated */ public byte [] pushES (Object reg) { return MOV (reg, relBPop (pushEStackOffs ())); } /** push the double-word value starting at the given register on to the eval stack * @param reg high-word register of value * @returns last instruction generated */ public byte [] LpushES (Object msreg, Object lsreg) { MOV (msreg, relBPop (pushEStackOffs ())); return MOV (lsreg, relBPop (pushEStackOffs ())); } /** push the value from the given FP register onto the evaluation stack * @returns code generated */ public byte [] FpushES () { return FSTP (relBPop (pushEStackOffs ()).setRefSize (4)); } /** push the double-word float starting at the given register on to the eval stack * @returns last instruction generated */ public byte [] DpushES () { pushEStackOffs (); return FSTP (relBPop (pushEStackOffs ()).setRefSize (8)); } /** put the value n words down from top of stack into register, without * changing the stack pointer. * @param n how far down to look * @param reg where value should go * @returns code generated */ public byte [] peekES (int n, Object reg) { return MOV (relBPop (peekEStackOffs (n)), reg); } /** replace the value n words down from top of stack with register, without * changing the stack pointer. * @param n how far down to look * @param reg where new value comes from go * @returns code generated */ public byte [] pokeES (int n, Object reg) { return MOV (reg, relBPop (peekEStackOffs (n))); } protected byte[] LOAD_REG (int val, Object reg) { return MOV (new Immediate (val, 4, false), reg); } protected byte [] RELATIVE_CALL (int offs) { return CALL (new Immediate (offs, 4, false)); } protected byte [] RELATIVE_JUMP (int offs) { return JMP (new Immediate (offs, 4, false)); } public static void TestIntel86 (String args []) { int i; int ia[]; Intel86 i86; BufferedReader stdin; String txt; byte rv[]; int aoutbase; i = 0; i86 = new Intel86 (null); /* Generate index for outputs based on starting at aoutbase. */ aoutbase = 52; /* Read lines from stdin, interpreting them as assembly instructions * and generating their code. */ stdin = new BufferedReader (new InputStreamReader (System.in)); while (true) { int si; int ei; String operation; String src; String dst; try { txt = stdin.readLine (); } catch (IOException e) { break; } if (null == txt) { break; } si = txt.indexOf ('#'); if (0 <= si) { txt = txt.substring (0, si); } si = 0; while ((txt.length() > si) && (' ' == txt.charAt (si))) { ++si; } if (txt.length() == si) { continue; } ei = si; while ((txt.length() > ei) && (' ' != txt.charAt (ei))) { ei++; } operation = txt.substring (si, ei); src = dst = null; si = ei; while ((txt.length() > si) && (' ' == txt.charAt (si))) { ++si; } ei = si; while ((txt.length() > ei) && (' ' != txt.charAt (ei))) { ++ei; } if (si < ei) { src = txt.substring (si, ei); } si = ei; while ((txt.length() > si) && (' ' == txt.charAt (si))) { ++si; } ei = si; while ((txt.length() > ei) && (' ' != txt.charAt (ei))) { ++ei; } if (si < ei) { dst = txt.substring (si, ei); } if (null == src) { src = "<missing>"; } if (null == dst) { dst = "<missing>"; } rv = new byte [0]; if (operation.equals ("mov")) { rv = i86.MOV (src, dst); } else if (operation.equals ("lea")) { rv = i86.LEA (src, dst); } else if (operation.equals ("add")) { rv = i86.ADD (src, dst); } else if (operation.equals ("push")) { rv = i86.PUSH (src); } else if (operation.equals ("pop")) { rv = i86.POP (src); } System.out.print ("# " + operation + " " + src + " " + dst + " ; [0" + Integer.toOctalString (aoutbase + i86.nextByteOffs() - rv.length) + "] "); emitByteArray (rv); } }/* ------------------------------------------------------ *//* From this point on, code is from the giIntel86 script. *//* Do not modify the following code. *//* ------------------------------------------------------ */include(Intel86.gi)}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -