x86stream.java

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

JAVA
2,052
字号
        writeModRM(0xf7, dstReg.getNr(), dstDisp, 3);
    }

    /**
     * Create a neg dstReg
     * 
     * @param dstReg
     */
    public final void writeNEG(Register dstReg) {
        writeModRR(0xf7, dstReg.getNr(), 3);
    }

    /**
     * Create a nop
     */
    public final void writeNOP() {
        write8(0x90);
    }

    /**
     * Create a OR dstReg, srcReg
     * 
     * @param dstReg
     * @param srcReg
     */
    public final void writeOR(Register dstReg, Register srcReg) {
        writeModRR(0x09, dstReg.getNr(), srcReg.getNr());
    }

    /**
     * Create a OR [dstReg+dstDisp], srcReg
     * 
     * @param dstReg
     * @param dstDisp
     * @param srcReg
     */
    public final void writeOR(Register dstReg, int dstDisp, Register srcReg) {
        writeModRM(0x09, dstReg.getNr(), dstDisp, srcReg.getNr());
    }

    /**
     * Create a sahf
     */
    public final void writeSAHF() {
        write8(0x9e);
    }

    /**
     * Create a SAL dstReg,cl
     * 
     * @param dstReg
     */
    public final void writeSAL_CL(Register dstReg) {
        writeModRR(0xd3, dstReg.getNr(), 4);
    }

    /**
     * Create a SAL dstReg,imm8
     * 
     * @param dstReg
     * @param imm8
     */
    public final void writeSAL(Register dstReg, int imm8) {
        writeModRR(0xc1, dstReg.getNr(), 4);
        write8(imm8);
    }

    /**
     * Create a SAR dstReg,cl
     * 
     * @param dstReg
     */
    public final void writeSAR_CL(Register dstReg) {
        writeModRR(0xd3, dstReg.getNr(), 7);
    }

    /**
     * Create a SAR dstReg,imm8
     * 
     * @param dstReg
     * @param imm8
     */
    public final void writeSAR(Register dstReg, int imm8) {
        writeModRR(0xc1, dstReg.getNr(), 7);
        write8(imm8);
    }

    /**
     * Create a SHL dstReg,cl
     * 
     * @param dstReg
     */
    public final void writeSHL_CL(Register dstReg) {
        writeModRR(0xd3, dstReg.getNr(), 4);
    }

    /**
     * Create a SHLD dstReg,srcReg,cl
     * 
     * @param dstReg
     * @param srcReg
     */
    public final void writeSHLD_CL(Register dstReg, Register srcReg) {
        write8(0x0f);
        writeModRR(0xa5, dstReg.getNr(), srcReg.getNr());
    }

    /**
     * Create a SHL dstReg,imm8
     * 
     * @param dstReg
     * @param imm8
     */
    public final void writeSHL(Register dstReg, int imm8) {
        writeModRR(0xc1, dstReg.getNr(), 4);
        write8(imm8);
    }

    /**
     * Create a SHR dstReg,cl
     * 
     * @param dstReg
     */
    public final void writeSHR_CL(Register dstReg) {
        writeModRR(0xd3, dstReg.getNr(), 5);
    }

    /**
     * Create a SHRD dstReg,srcReg,cl
     * 
     * @param dstReg
     * @param srcReg
     */
    public final void writeSHRD_CL(Register dstReg, Register srcReg) {
        write8(0x0f);
        writeModRR(0xad, dstReg.getNr(), srcReg.getNr());
    }

    /**
     * Create a SHL dstReg,imm8
     * 
     * @param dstReg
     * @param imm8
     */
    public final void writeSHR(Register dstReg, int imm8) {
        writeModRR(0xc1, dstReg.getNr(), 5);
        write8(imm8);
    }

    /**
     * Create a SBB dstReg, srcReg
     * 
     * @param dstReg
     * @param srcReg
     */
    public final void writeSBB(Register dstReg, Register srcReg) {
        writeModRR(0x19, dstReg.getNr(), srcReg.getNr());
    }

    /**
     * Create a SBB dstReg, imm32
     * 
     * @param dstReg
     * @param imm32
     */
    public void writeSBB(Register dstReg, int imm32) {
        if (X86Utils.isByte(imm32)) {
            writeModRR(0x83, dstReg.getNr(), 3);
            write8(imm32);
        } else {
            writeModRR(0x81, dstReg.getNr(), 3);
            write32(imm32);
        }
    }

    /**
     * Create a SBB dword [dstReg+dstDisp], <imm32>
     * 
     * @param dstReg
     * @param dstDisp
     * @param imm32
     */
    public final void writeSBB(Register dstReg, int dstDisp, int imm32) {
        if (X86Utils.isByte(imm32)) {
            writeModRM(0x83, dstReg.getNr(), dstDisp, 3);
            write8(imm32);
        } else {
            writeModRM(0x81, dstReg.getNr(), dstDisp, 3);
            write32(imm32);
        }
    }

    /**
     * Create a SBB [dstReg+dstDisp], <srcReg>
     * 
     * @param dstReg
     * @param dstDisp
     * @param srcReg
     */
    public final void writeSBB(Register dstReg, int dstDisp, Register srcReg) {
        writeModRM(0x19, dstReg.getNr(), dstDisp, srcReg.getNr());
    }

    /**
     * Create a SUB dstReg, srcReg
     * 
     * @param dstReg
     * @param srcReg
     */
    public final void writeSUB(Register dstReg, Register srcReg) {
        writeModRR(0x29, dstReg.getNr(), srcReg.getNr());
    }

	/**
	 * Create a SUB reg, imm32
	 * 
	 * @param reg
	 * @param imm32
	 */
	public final void writeSUB(Register reg, int imm32) {
	    writeModRR(0x81, reg.getNr(), 5);
	    write32(imm32);
	}
	
    /**
     * Create a SUB [dstReg+dstDisp], <srcReg>
     * 
     * @param dstReg
     * @param dstDisp
     * @param srcReg
     */
    public final void writeSUB(Register dstReg, int dstDisp, Register srcReg) {
        writeModRM(0x29, dstReg.getNr(), dstDisp, srcReg.getNr());
    }

    /**
     * Create a XOR dstReg, srcReg
     * 
     * @param dstReg
     * @param srcReg
     */
    public final void writeXOR(Register dstReg, Register srcReg) {
        writeModRR(0x31, dstReg.getNr(), srcReg.getNr());
    }

    /**
     * Create a XOR [dstReg+dstDisp], srcReg
     * 
     * @param dstReg
     * @param dstDisp
     * @param srcReg
     */
    public final void writeXOR(Register dstReg, int dstDisp, Register srcReg) {
        writeModRM(0x31, dstReg.getNr(), dstDisp, srcReg.getNr());
    }

    /**
     * Start a new object and write its header. An ObjectInfo object is
     * returned, on which the <code>markEnd</code> mehod must be called after
     * all data has been written into the object.
     * 
     * @param cls
     * @see ObjectInfo
     * @return The info for the started object
     */
    public final ObjectInfo startObject(VmType cls) {
        if (inObject) { throw new RuntimeException(
                "Cannot start an object within an object"); }
        if (align(ObjectLayout.OBJECT_ALIGN) != 0) { throw new RuntimeException(
                "Unaligned before startObject"); }
        inObject = true;

        // The default header is 8-bytes long. The size fields add another
        // 4 bytes, which adds up to 12 which masy not be objectaligned.
        // Write some slack until it is aligned again
        int alignSlack = 0;
        while (ObjectLayout.objectAlign(alignSlack + 12) != (alignSlack + 12)) {
            write32(0);
            alignSlack += 4;
        }
        //System.out.println("alignSlack=" + alignSlack);

        write32(0); // Size
        write32(ObjectFlags.GC_DEFAULT_COLOR); // Flags
        if (cls == null) {
            throw new NullPointerException("cls==null");
        } else {
            final Object[] tib = ((VmClassType) cls).getTIB();
            if (tib[ 0] == null) { throw new NullPointerException(
                    "tib[0]==null"); }
            writeObjectRef(tib);
        }
        return new X86ObjectInfo();
    }

    /**
     * Create 32-bit reference to an absolute address like: dd label
     * 
     * @param object
     */
    public final void writeObjectRef(Object object) {
        writeObjectRef(object, 0, false);
    }

    /**
     * Create 32-bit reference to an absolute address like: dd label
     * 
     * @param object
     * @param offset
     * @param rawAddress
     *            If true, object is a raw address, not a normal object.
     */
    private final void writeObjectRef(Object object, int offset,
            boolean rawAddress) {
        if (object == null) {
            write32(offset);
        } else if (rawAddress) {
            write32(resolver.addressOf32(object) + offset);
        } else if ((resolver != null) && (!(object instanceof Label))) {
            //System.out.println("Using resolver for " + object);
            write32(resolver.addressOf32(object) + offset);
        } else {
            final X86ObjectRef ref = (X86ObjectRef) getObjectRef(object);
            if (ref.isResolved())
                write32(ref.getOffset() + baseAddr + offset);
            else {
                ref.addUnresolvedLink(m_used);
                write32(-(baseAddr + offset));
            }
        }
    }

    /**
     * Create a pop reg32
     * 
     * @param dstReg
     */
    public final void writePOP(Register dstReg) {
        write8(0x58 + dstReg.getNr()); // POP reg32
    }

    /**
     * Create a pop dword [reg32+disp]
     * 
     * @param dstReg
     * @param dstDisp
     */
    public final void writePOP(Register dstReg, int dstDisp) {
        writeModRM(0x8f, dstReg.getNr(), dstDisp, 0); // POP [reg32+disp]
    }

    /**
     * Create a push dword <imm32>
     * 
     * @param imm32
     * @return The ofset of the start of the instruction.
     */
    public final int writePUSH(int imm32) {
        final int rc = m_used;
        write8(0x68); // PUSH imm32
        write32(imm32);
        return rc;
    }

    /**
     * Create a push reg32
     * 
     * @param srcReg
     * @return The ofset of the start of the instruction.
     */
    public final int writePUSH(Register srcReg) {
        final int rc = m_used;
        write8(0x50 + srcReg.getNr()); // PUSH reg32
        return rc;
    }

    /**
     * Create a push dword [reg32+disp]
     * 
     * @param srcReg
     * @param srcDisp
     * @return The ofset of the start of the instruction.
     */
    public final int writePUSH(Register srcReg, int srcDisp) {
        final int rc = m_used;
        writeModRM(0xFF, srcReg.getNr(), srcDisp, 6); // PUSH [reg32+disp]
        return rc;
    }

    /**
     * Create a push dword [baseReg+indexReg*scale+disp]
     * 
     * @param srcBaseReg
     * @param srcIndexReg
     * @param srcScale
     * @param srcDisp
     * @return The ofset of the start of the instruction.
     */
    public final int writePUSH(Register srcBaseReg, Register srcIndexReg,
            int srcScale, int srcDisp) {
        final int rc = m_used;
        writeModRMSib(0xFF, srcBaseReg.getNr(), srcDisp, 6, srcScale,
                srcIndexReg.getNr());
        return rc;
    }

    /**
     * Create a ret near to caller
     */
    public final void writeRET() {
        write8(0xc3);
    }

    /**
     * Create a ret imm16 near to caller
     * 
     * @param imm16
     */
    public final void writeRET(int imm16) {
        write8(0xc2);
        write16(imm16);
    }

    /**
     * Create a TEST al, imm8
     * 
     * @param value
     */
    public final void writeTEST_AL(int value) {
        write8(0xa8);
        write8(value);
    }

    /**
     * Create a TEST eax, imm32
     * 
     * @param value
     */
    public final void writeTEST_EAX(int value) {
        write8(0xa9);
        write32(value);
    }

    /**
     * Create a TEST reg, imm32
     * 
     * @param reg
     * @param imm32
     */
    public final void writeTEST(Register reg, int imm32) {
        writeModRR(0xF7, reg.getNr(), 0);
        write32(imm32);
    }

    /**
     * Create a TEST reg1, reg2
     * 
     * @param reg1
     * @param reg2
     */
    public void writeTEST(Register reg1, Register reg2) {
        writeModRR(0x85, reg1.getNr(), reg2.getNr());
    }

    /**
     * Create 32-bit offset relative to the current (after this offset) offset.
     * 
     * @param object
     */
    public final void writeRelativeObjectRef(Label object) {
        if (object == null) { throw new NullPointerException(); }

        int ofs = m_used + 4;
        X86ObjectRef ref = (X86ObjectRef) getObjectRef(object);
        ref.setRelJump();
        if (ref.isResolved()) {
            write32(ref.getOffset() - ofs);
        } else {
            ref.addUnresolvedLink(m_used);
            write32(ofs);
        }
    }

    /**
     * Write my contents to the given stream.
     * 
     * @param os
     * @throws IOException
     */
    public final void writeTo(OutputStream os) throws IOException {
        os.write(m_data, 0, m_used);
    }

    /**
     * Is logging enabled. This method will only return true on on debug like
     * implementations.
     * 
     * @return boolean
     */
    public boolean isLogEnabled() {
        return false;
    }

    /**
     * Write a log message. This method is only implemented on debug like
     * implementations.
     * 
     * @param msg
     */
    public void log(Object msg) {
        // Do nothing
    }
}

⌨️ 快捷键说明

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