📄 intel86.j4
字号:
base: 0 iff (undefined base)disp: 0 iff (0 == disp)scale index base disp MOD RM sib?0 0 0 0 set emitdisp to true/8bit and use 00 101 -*/ case 0x00: emitdisp = true; smdisp = true; mod = 0x00; rm = 0x05; break;/*scale index base disp MOD RM sib?0 0 0 1 00 101 -*/ case 0x01: mod = 0x00; rm = 0x05; break;/*scale index base disp MOD RM sib?0 0 1 0 if base is %esp 00 100 (00)(100)(brn) if base is %ebp, set emitdisp to true/8bit and use 01 brn - else 00 brn -*/ case 0x02: if (Register.R_esp == mdst.getBaseReg ()) { mod = 0x00; rm = 0x04; sibv = 0x24; break; } if (Register.R_ebp == mdst.getBaseReg ()) { emitdisp = true; smdisp = true; mod = 0x01; rm = mdst.getBaseReg ().getRegBitName(); break; } mod = 0x00; rm = mdst.getBaseReg ().getRegBitName (); break;/*scale index base disp MOD RM sib?0 0 1 1 if base is %esp dm 100 (00)(100)(brn) else dm brn -*/ case 0x03: if (Register.R_esp == mdst.getBaseReg ()) { rm = 0x04; sibv = 0x24; } rm = mdst.getBaseReg ().getRegBitName (); break;/*scale index base disp MOD RM sib?0 1 0 0 if index is %esp, illegal (index %esp) if index is %ebp, set emitdisp to true/8bit and use 01 irn - else 00 irn -*/ case 0x04: /* Illegal %esp index caught by verify */ if (Register.R_ebp == mdst.getIndexReg ()) { emitdisp = true; smdisp = true; mod = 0x01; rm = mdst.getIndexReg ().getRegBitName (); break; } mod = 0x00; rm = mdst.getIndexReg ().getRegBitName (); break;/* scale index base disp MOD RM sib?0 1 0 1 if index is %esp illegal (index %esp) else dm irn -*/ case 0x05: /* Illegal %esp index caught by verify */ rm = mdst.getIndexReg ().getRegBitName (); break;/*scale index base disp MOD RM sib?0 1 1 0 if index is %esp, illegal (index %esp) if index and base are both %ebp, set emitdisp true/8bit, and use 01 100 (00)(irn)(brn) if base is %ebp, swap index and base, fallthru use always: 00 100 (00)(irn)(brn)*/ case 0x06: /* Illegal %esp index, %ebp base, caught by verify */ if ((Register.R_ebp == mdst.getIndexReg ()) && (Register.R_ebp == mdst.getBaseReg ())) { emitdisp = true; smdisp = true; mod = 0x01; rm = 0x04; sibv = 0x2D; break; } mod = 0x00; rm = 0x04; sibv = (((mdst.getIndexReg().getRegBitName()) << 3) | (mdst.getBaseReg().getRegBitName())); break;/*scale index base disp MOD RM sib?0 1 1 1 dm 100 (00)(irn)(brn)*/ case 0x07: rm = 0x04; sibv = (((mdst.getIndexReg().getRegBitName()) << 3) | (mdst.getBaseReg().getRegBitName())); break;/*scale index base disp MOD RM sib?1 0 0 0 illegal1 0 0 1 illegal1 0 1 0 illegal1 0 1 1 illegal*/ case 0x08: case 0x09: case 0x0A: case 0x0B: illegal = "scale without index"; break;/*scale index base disp MOD RM sib?1 1 0 0 if index is %esp illegal else set emitdisp to true/32bit, and use 00 100 (sf)(irn)(101)*/ case 0x0C: /* Illegal %esp index caught by verify */ emitdisp = true; smdisp = false; // special case 00/100 is a 32bit disp mod = 0x00; rm = 0x04; sibv = (sf << 6) | (mdst.getIndexReg ().getRegBitName() << 3) | 0x05; break;/*scale index base disp MOD RM sib?1 1 0 1 index is %esp illegal (index %esp) else set emitdisp to true/32bit, and use 00 100 (sf)(irn)(101)*/ case 0x0D: mod = 0x00; rm = 0x04; smdisp = false; // special case 00/100 is a 32bit disp sibv = (sf << 6) | (mdst.getIndexReg ().getRegBitName() << 3) | 0x05; break;/* scale index base disp MOD RM sib?1 1 1 0 if index is %esp illegal (index %esp) if base is %ebp, set emitdisp to true/8bit and use 01 100 (sf)(irn)(brn) else: 00 100 (sf)(irn)(brn)*/ case 0x0E: /* Illegal %esp index caught by verify */ if (Register.R_ebp == mdst.getBaseReg ()) { emitdisp = true; smdisp = true; mod = 0x01; rm = 0x04; sibv = ((sf << 6) | ((mdst.getIndexReg().getRegBitName()) << 3) | (mdst.getBaseReg().getRegBitName())); break; } mod = 0x00; rm = 0x04; sibv = ((sf << 6) | ((mdst.getIndexReg().getRegBitName()) << 3) | (mdst.getBaseReg().getRegBitName())); break;/*scale index base disp MOD RM sib?1 1 1 1 if index is %esp illegal else dm 100 (sf)(irn)(brn)*/ case 0x0F: /* Illegal %esp index caught by verify */ rm = 0x04; sibv = ((sf << 6) | ((mdst.getIndexReg().getRegBitName()) << 3) | (mdst.getBaseReg().getRegBitName())); break; default: throw new InternalError ("Illegal sibd value"); } /* Report any errors we discovered */ if (null != illegal) { throw new InternalError ("x86: Illegal mem operand: " + illegal); } } /* Set up or override the fields based on the types of the * source and dest. This does basic sanity checking given what * it knows; the caller must have already verified that the sot/dot * do not specify an operand set that is inappropriate for the * operation. */ switch ((sot << 4) + dot) { case ((OT_reg << 4) + OT_reg): /* Can't mix 8 and 32bit registers */ if (((Register)src).is8BitReg() != ((Register)dst).is8BitReg ()) { throw new InternalError ("x86: Mixing 8bit (" + src + ") and 32bit (" + dst + ") registers"); } reg = ((Register)src).getRegBitName (); rm = ((Register)dst).getRegBitName (); break; case ((OT_reg << 4) + OT_mem): reg = ((Register)src).getRegBitName (); break; case ((OT_absent << 4) + OT_reg): case ((OT_imm << 4) + OT_reg): case ((OT_absent << 4) + OT_fpstack): rm = ((Register)dst).getRegBitName (); break; case ((OT_imm << 4) + OT_mem): case ((OT_absent << 4) + OT_mem): // Everything's already set up. break; default: throw new InternalError ("Invalid src,dst types (" + sot + ", " + dot + ")"); } rvs = 0; /* Build the ModR/M byte. */ rv [rvs++] = (byte) ((mod << 6) | (reg << 3) | rm); /* Add the SIB byte, if present */ if (0 <= sibv) { rv [rvs++] = (byte) sibv; } /* Add displacement, of appropriate length, if present. */ if (emitdisp) { if (smdisp) { rv [rvs++] = (byte) dispv; } else { /* Store little-endian */ rv [rvs++] = (byte) ((dispv >> 0) & 0xFF); rv [rvs++] = (byte) ((dispv >> 8) & 0xFF); rv [rvs++] = (byte) ((dispv >> 16) & 0xFF); rv [rvs++] = (byte) ((dispv >> 24) & 0xFF); } } /* Return an array that's exactly the right size, since the * caller can't infer the length. */ byte nrv[] = new byte [rvs]; while (0 <= --rvs) { nrv [rvs] = rv [rvs]; } return nrv; } /** Build a mod/rm sequence for a unary operation, where the reg * field encodes a 3-bit opcode modifier. * @param auxop 3-bit opcode modifier * @param dst Dest operand * @returns byte[] Array of bytes encoding instruction */ private byte [] makeModRM (int auxop, // Opcode modifier Object op) // Singleton operand { byte rv []; rv = makeModRM (null, op); /* Replace the reg field with the opcode modifier. There better * not be anything there already. */ if (0 != (rv [0] & 0x38)) { throw new InternalError ("Intel86: Unexpected extopcode ModRM value " + Integer.toHexString (rv [0])); } if ((auxop & 0x07) != auxop) { throw new InternalError ("Intel86: Opcode modifier too big: " + Integer.toHexString (auxop)); } rv [0] |= (auxop << 3); return rv; } /** Combine an opcode, modrm, and immediate sequence into an Intel86 * instruction, and store it into the code block. * @param opcode array of opcode * @param modrm array of modrm, sib, and displacement * @param immed immediate operand * @returns byte[] instruction bytes. */ private byte [] encode (byte opcode[], // Opcode byte modrm[], // Mod/RM and displacement byte immed[]) // Immediate operand { byte rv []; // Resulting instruction array int rvs; // Length of instruction so far int i; // Index over instruction component arrays /* Figure out how long this thing should be. */ rvs = 0; if (null != opcode) { rvs += opcode.length; } if (null != modrm) { rvs += modrm.length; } if (null != immed) { rvs += immed.length; } /* Allocate the array, and copy each component into it * in turn. */ rv = new byte [rvs]; rvs = 0; if (null != opcode) { i = 0; while (i < opcode.length) { rv [rvs++] = opcode [i++]; } } if (null != modrm) { i = 0; while (i < modrm.length) { rv [rvs++] = modrm [i++]; } } if (null != immed) { i = 0; while (i < immed.length) { rv [rvs++] = immed [i++]; } } /* Add the instruction to the end of the code block. */ return addByteArray (rv); } /** Return a single-element byte array with parameter as element. * @param b0 value to store in array * @returns byte[] array of b0 */ private byte [] makeByteArray (int b0) { byte rv [] = new byte [1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -