x86stream.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 2,052 行 · 第 1/4 页

JAVA
2,052
字号
    public final void writeINT(int vector) {
        write8(0xCD);
        write8(vector);
    }

    /**
     * Create a conditional jump to a label The opcode sequence is: 0x0f
     * <jumpOpcode><rel32>
     * 
     * @param label
     * @param jumpOpcode
     */
    public final void writeJCC(Label label, int jumpOpcode) {
        write8(0x0f); // jxx rel32
        write8(jumpOpcode);
        writeRelativeObjectRef(label);
    }

    /**
     * Create a relative jump to a given label
     * 
     * @param label
     */
    public final void writeJMP(Label label) {
        write8(0xe9); // jmp rel32
        writeRelativeObjectRef(label);
    }

    /**
     * Create a absolute jump to address stored at the given offset in the
     * given table pointer.
     * 
     * @param tablePtr
     * @param offset
     * @param rawAddress
     *            If true, tablePtr is a raw address
     */
    public void writeJMP(Object tablePtr, int offset, boolean rawAddress) {
        write8(0xFF); // Opcode
        write8(0x25); // effective address == disp32
        writeObjectRef(tablePtr, offset, rawAddress);
    }

    /**
     * Create a absolute jump to address stored at the given offset (in
     * register) in the given table pointer.
     * 
     * @param tablePtr
     * @param offsetReg
     */
    public void writeJMP(Object tablePtr, Register offsetReg) {
        write8(0xFF); // Opcode
        write8(0xA0 | offsetReg.getNr()); // effective address == disp32[reg]
        writeObjectRef(tablePtr);
    }

    /**
     * Create a absolute jump to address in register
     * 
     * @param reg32
     */
    public final void writeJMP(Register reg32) {
        writeModRR(0xff, reg32.getNr(), 4);
    }

	/**
	 * Create a absolute jump to [reg32+disp]
	 * @param reg32
	 */
	public final void writeJMP(Register reg32, int disp) {
        write8(0xFF); // Opcode
        write8(0xA0 | reg32.getNr()); // effective address == disp32[reg]
        write32(disp);
	}
	
    /**
     * Create a LOOP label instruction. The given label must have be resolved
     * before!
     * 
     * @param label
     * @throws UnresolvedObjectRefException
     */
    public final void writeLOOP(Label label)
            throws UnresolvedObjectRefException {
        final ObjectRef ref = getObjectRef(label);
        if (ref.isResolved()) {
            write8(0xE2);
            final int offset = m_used + 1;
            int distance = ref.getOffset() - offset;
            if (X86Utils.isByte(distance)) {
                write8(distance);
            } else {
                throw new UnresolvedObjectRefException("Label " + label
                        + " is out of range (distance " + distance + ")");
            }
        } else {
            throw new UnresolvedObjectRefException("Label " + label
                    + " is not resolved");
        }
    }

    /**
     * Write a mod-r/m byte+offset for the following addressing scheme's [rm]
     * disp8[rm] disp32[rm]
     * 
     * @param rm
     * @param disp
     * @param reg
     */
    public final void writeModRM(int rm, int disp, int reg) {
        if ((rm < 0) || (rm > 7)) { throw new IllegalArgumentException("rm"); }
        if ((reg < 0) || (reg > 7)) { throw new IllegalArgumentException("reg"); }
        if (rm == X86Constants.rESP) {
            if (X86Utils.isByte(disp)) {
                write8(0x40 | (reg << 3) | rm);
                write8(0x24);
                write8(disp);
            } else {
                write8(0x80 | (reg << 3) | rm);
                write8(0x24);
                write32(disp);
            }
        } else {
            if ((disp == 0) && (rm != X86Constants.rEBP)) {
                write8(0x00 | (reg << 3) | rm);
            } else if (X86Utils.isByte(disp)) {
                write8(0x40 | (reg << 3) | rm);
                write8(disp);
            } else {
                write8(0x80 | (reg << 3) | rm);
                write32(disp);
            }
        }
    }

    /**
     * Write a 1-byte instruction followed by a mod-r/m byte+offset for the
     * following addressing scheme's [rm] disp8[rm] disp32[rm]
     * 
     * @param opcode
     * @param rm
     * @param disp
     * @param reg
     */
    public final void writeModRM(int opcode, int rm, int disp, int reg) {
        write8(opcode);
        writeModRM(rm, disp, reg);
    }

    /**
     * Write a mod-r/m byte+offset+scale+index+base for the following
     * addressing scheme's [rm] disp8[rm] disp32[rm] To create <code>[index*scale+disp]</code>
     * code, set base to -1.
     * 
     * @param base
     * @param disp
     * @param reg
     * @param scale
     * @param index
     */
    public final void writeModRMSib(int base, int disp, int reg, int scale,
            int index) {
        if ((base < -1) || (base > 7))
                throw new IllegalArgumentException("base");
        if ((reg < 0) || (reg > 7)) throw new IllegalArgumentException("reg");
        if ((index < 0) || (index > 7))
                throw new IllegalArgumentException("index");

        switch (scale) {
        case 1:
            scale = 0;
            break;
        case 2:
            scale = 1;
            break;
        case 4:
            scale = 2;
            break;
        case 8:
            scale = 3;
            break;
        default:
            throw new IllegalArgumentException("scale");
        }

        if (base == -1) {
            write8(0x00 | (reg << 3) | 4);
            write8((scale << 6) | (index << 3) | 5);
            write32(disp);
        } else if ((disp == 0) && (base != X86Constants.rEBP)) {
            write8(0x00 | (reg << 3) | 4);
            write8((scale << 6) | (index << 3) | base);
        } else if (X86Utils.isByte(disp)) {
            write8(0x40 | (reg << 3) | 4);
            write8((scale << 6) | (index << 3) | base);
            write8(disp);
        } else {
            write8(0x80 | (reg << 3) | 4);
            write8((scale << 6) | (index << 3) | base);
            write32(disp);
        }
    }

    /**
     * Write a 1-byte instruction followed by a mod-r/m byte+offset for the
     * following addressing scheme's [rm] disp8[rm] disp32[rm]
     * 
     * @param opcode
     * @param base
     * @param disp
     * @param reg
     * @param scale
     * @param index
     */
    public final void writeModRMSib(int opcode, int base, int disp, int reg,
            int scale, int index) {
        write8(opcode);
        writeModRMSib(base, disp, reg, scale, index);
    }

    /**
     * Write a mod-r/m byte for the following addressing scheme rm
     * 
     * @param rm
     * @param reg
     */
    public final void writeModRR(int rm, int reg) {
        if ((rm < 0) || (rm > 7)) throw new IllegalArgumentException("rm");
        if ((reg < 0) || (reg > 7)) throw new IllegalArgumentException("reg");
        write8(0xc0 | (reg << 3) | rm);
    }

    /**
     * Write a 1-byte instruction followed by a mod-r/m byte for the following
     * addressing scheme rm
     * 
     * @param opcode
     * @param rm
     * @param reg
     */
    public final void writeModRR(int opcode, int rm, int reg) {
        write8(opcode);
        writeModRR(rm, reg);
    }

    /**
     * Create a lea dstReg,[srcReg+disp]
     * 
     * @param dstReg
     * @param srcReg
     * @param disp
     */
    public final void writeLEA(Register dstReg, Register srcReg, int disp) {
        writeModRM(0x8d, srcReg.getNr(), disp, dstReg.getNr());
    }

    /**
     * Create a lea dstReg,[srcReg+srcIdxReg*scale+disp]
     * 
     * @param dstReg
     * @param srcReg
     * @param srcIdxReg
     * @param scale
     * @param disp
     */
    public final void writeLEA(Register dstReg, Register srcReg,
            Register srcIdxReg, int scale, int disp) {
        writeModRMSib(0x8d, srcReg.getNr(), disp, dstReg.getNr(), scale,
                srcIdxReg.getNr());
    }

    /**
     * Create a LODSD
     */
    public final void writeLODSD() {
        write8(0xAD);
    }

    /**
     * Create a mov <reg>, <imm32>
     * 
     * @param destReg
     * @param imm32
     */
    public final void writeMOV_Const(Register destReg, int imm32) {
        write8(0xb8 + destReg.getNr()); // MOV reg,imm32
        write32(imm32);
    }

    /**
     * Create a mov [destReg+destDisp], <imm32>
     * 
     * @param destReg
     * @param destDisp
     * @param imm32
     */
    public final void writeMOV_Const(Register destReg, int destDisp, int imm32) {
        writeModRM(0xC7, destReg.getNr(), destDisp, 0);
        write32(imm32);
    }

    /**
     * Create a mov <dstReg>, <srcReg>
     * 
     * @param operandSize
     * @param dstReg
     * @param srcReg
     */
    public final void writeMOV(int operandSize, Register dstReg, Register srcReg) {
        final int opcode;
        switch (operandSize) {
        case X86Constants.BITS8:
            opcode = 0x88;
            break;
        case X86Constants.BITS16:
            opcode = 0x89;
            write8(OSIZE_PREFIX);
            break;
        case X86Constants.BITS32:
            opcode = 0x89;
            break;
        default:
            throw new IllegalArgumentException("Invalid operandSize "
                    + operandSize);
        }
        writeModRR(opcode, dstReg.getNr(), srcReg.getNr());
    }

    /**
     * Create a mov [dstReg+dstDisp], <srcReg>
     * 
     * @param operandSize
     * @param dstReg
     * @param dstDisp
     * @param srcReg
     */
    public final void writeMOV(int operandSize, Register dstReg, int dstDisp,
            Register srcReg) {
        final int opcode;
        switch (operandSize) {
        case X86Constants.BITS8:
            opcode = 0x88;
            break;
        case X86Constants.BITS16:
            opcode = 0x89;
            write8(OSIZE_PREFIX);
            break;
        case X86Constants.BITS32:
            opcode = 0x89;
            break;
        default:
            throw new IllegalArgumentException("Invalid operandSize "
                    + operandSize);
        }
        writeModRM(opcode, dstReg.getNr(), dstDisp, srcReg.getNr());
    }

    /**
     * Create a mov [dstReg+dstIdxReg*scale+dstDisp], <srcReg>
     * 
     * @param operandSize
     * @param dstReg
     * @param dstIdxReg
     * @param scale
     * @param dstDisp
     * @param srcReg
     */
    public final void writeMOV(int operandSize, Register dstReg,
            Register dstIdxReg, int scale, int dstDisp, Register srcReg) {
        final int opcode;
        switch (operandSize) {
        case X86Constants.BITS8:
            opcode = 0x88;
            break;
        case X86Constants.BITS16:
            opcode = 0x89;
            write8(OSIZE_PREFIX);
            break;
        case X86Constants.BITS32:
            opcode = 0x89;
            break;
        default:
            throw new IllegalArgumentException("Invalid operandSize "
                    + operandSize);
        }
        writeModRMSib(opcode, dstReg.getNr(), dstDisp, srcReg.getNr(), scale,
                dstIdxReg.getNr());
    }

    /**
     * Create a mov dstReg, [srcReg+srcDisp]
     * 
     * @param operandSize
     * @param dstReg
     * @param srcReg
     * @param srcDisp
     */
    public final void writeMOV(int operandSize, Register dstReg,
            Register srcReg, int srcDisp) {
        final int opcode;
        switch (operandSize) {
        case X86Constants.BITS8:
            opcode = 0x8a;
            break;
        case X86Constants.BITS16:
            opcode = 0x8b;
            write8(OSIZE_PREFIX);
            break;
        case X86Constants.BITS32:
            opcode = 0x8b;
            break;
        default:
            throw new IllegalArgumentException("Invalid operandSize "
                    + operandSize);
        }
        writeModRM(opcode, srcReg.getNr(), srcDisp, dstReg.getNr());
    }

    /**
     * Create a mov dstReg, [srcReg+srcIdxReg*scale+srcDisp]
     * 
     * @param operandSize
     * @param dstReg
     * @param srcReg
     * @param srcIdxReg
     * @param scale
     * @param srcDisp
     */
    public final void writeMOV(int operandSize, Register dstReg,
            Register srcReg, Register srcIdxReg, int scale, int srcDisp) {
        final int opcode;
        switch (operandSize) {
        case X86Constants.BITS8:
            opcode = 0x8a;
            break;
        case X86Constants.BITS16:
            opcode = 0x8b;
            write8(OSIZE_PREFIX);
            break;
        case X86Constants.BITS32:
            opcode = 0x8b;
            break;
        default:
            throw new IllegalArgumentException("Invalid operandSize "
                    + operandSize);
        }
        writeModRMSib(opcode, srcReg.getNr(), srcDisp, dstReg.getNr(), scale,
                srcIdxReg.getNr());
    }

    /**
     * Create a mov <reg>, <label>
     * 
     * @param dstReg
     * @param label
     */
    public final void writeMOV_Const(Register dstReg, Object label) {
        write8(0xb8 + dstReg.getNr());
        writeObjectRef(label);
    }

    /**
     * Create a movsx <dstReg>, <srcReg>
     * 
     * @param dstReg
     * @param srcReg
     * @param srcSize
     */
    public final void writeMOVSX(Register dstReg, Register srcReg, int srcSize) {
        write8(0x0f);
        if (srcSize == X86Constants.BITS8) {
            writeModRR(0xBE, srcReg.getNr(), dstReg.getNr());
        } else if (srcSize == X86Constants.BITS16) {
            writeModRR(0xBF, srcReg.getNr(), dstReg.getNr());
        } else {
            throw new IllegalArgumentException("Unknown srcSize " + srcSize);
        }
    }

    /**
     * Create a movzx <dstReg>, <srcReg>
     * 
     * @param dstReg
     * @param srcReg
     * @param srcSize
     */
    public final void writeMOVZX(Register dstReg, Register srcReg, int srcSize) {
        write8(0x0f);
        if (srcSize == X86Constants.BITS8) {
            writeModRR(0xB6, srcReg.getNr(), dstReg.getNr());
        } else if (srcSize == X86Constants.BITS16) {
            writeModRR(0xB7, srcReg.getNr(), dstReg.getNr());
        } else {
            throw new IllegalArgumentException("Unknown srcSize " + srcSize);
        }
    }

    /**
     * Create a mul eax, srcReg
     * 
     * @param srcReg
     */
    public final void writeMUL_EAX(Register srcReg) {
        writeModRR(0xF7, srcReg.getNr(), 4);
    }

    /**
     * Create a neg dword [dstReg+dstDisp]
     * 
     * @param dstReg
     * @param dstDisp
     */
    public final void writeNEG(Register dstReg, int dstDisp) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?