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 + -
显示快捷键?