Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package emulator.editor;
- import java.nio.*;
- import java.util.Vector;
- import emulator.code.Operation.OperationType;
- import emulator.code.Operation.OperationType.IExecuteExpression;
- import emulator.editor.Export.BytecodeOffset;
- import emulator.editor.Export.IntelInstruction;
- public class ExportOpcode {
- // all 32 bit int, 80 bit float
- // calculate ax, cx
- // address: bx
- // port/string: dx
- // move ax to cx
- // condition: test
- // logic compare: cmp
- // opt: prefix (1b)
- // opcode (2-3b)
- // opt: modr/m (1b)
- // opt: sib (1b) TODO use for fixed size array pages
- // opt: disp/const (1-4b)
- // TODO list and deassemble all opcodes & check
- // use tmp registers, fpu stack
- // provide access:
- // segment register, task register, ldtr, tss, gdtr, idtr
- // stack pointer
- // flag register read
- // cr0-4, dr0-7
- // provide opcodes:
- // lea, lmsw, smsw, rdpmc, rdtsc, cpuid
- // int/float byte size conversion (cbw, ..., movsx/zx)
- // std, cld, sti, cli
- // rep (dma?), string, port
- // TODO: ask: register, opcodes, stack (interrupt), ldtr, tss, physical address bx, call gate
- // TODO SETx insert leading XOR (8bit -> 32bit)
- /*public static final byte mod_rm_ax_p = (byte) Integer.parseInt("00000000", 2);
- public static final byte mod_rm_cx_p = (byte) Integer.parseInt("00000001", 2);
- public static final byte mod_rm_dx_p = (byte) Integer.parseInt("00000010", 2);*/
- public static final byte mod_rm_bx_p = (byte) Integer.parseInt("00000011", 2);
- public static final byte mod_rm_ax = (byte) Integer.parseInt("11000000", 2);
- public static final byte mod_rm_cx = (byte) Integer.parseInt("11000001", 2);
- public static final byte mod_rm_dx = (byte) Integer.parseInt("11000010", 2);
- public static final byte mod_rm_bx = (byte) Integer.parseInt("11000011", 2);
- /*public static final byte mod_rm_sp = (byte) Integer.parseInt("11000100", 2);
- public static final byte mod_rm_bp = (byte) Integer.parseInt("11000101", 2);
- public static final byte mod_rm_si = (byte) Integer.parseInt("11000110", 2);
- public static final byte mod_rm_di = (byte) Integer.parseInt("11000111", 2);*/
- public static final byte mod_op_0 = (byte) Integer.parseInt("00000000", 2);
- public static final byte mod_op_1 = (byte) Integer.parseInt("00001000", 2);
- public static final byte mod_op_2 = (byte) Integer.parseInt("00010000", 2);
- public static final byte mod_op_3 = (byte) Integer.parseInt("00011000", 2);
- public static final byte mod_op_4 = (byte) Integer.parseInt("00100000", 2);
- public static final byte mod_op_5 = (byte) Integer.parseInt("00101000", 2);
- public static final byte mod_op_6 = (byte) Integer.parseInt("00110000", 2);
- public static final byte mod_op_7 = (byte) Integer.parseInt("00111000", 2);
- public static final byte mod_reg_ax = mod_op_0;
- public static final byte mod_reg_cx = mod_op_1;
- public static final byte mod_reg_dx = mod_op_2;
- public static final byte mod_reg_bx = mod_op_3;
- /*public static final byte mod_reg_sp = mod_op_4;
- public static final byte mod_reg_bp = mod_op_5;
- public static final byte mod_reg_si = mod_op_6;
- public static final byte mod_reg_di = mod_op_7;*/
- public static final byte add_ax = 0;
- public static final byte add_cx = 1;
- public static final byte add_dx = 2;
- public static final byte add_bx = 3;
- /*public static final byte add_sp = 4;
- public static final byte add_bp = 5;
- public static final byte add_si = 6;
- public static final byte add_di = 7;*/
- public static final byte sel_ax = 0;
- public static final byte sel_cx = 1;
- /*public static final byte sel_dx = 2;
- public static final byte sel_bx = 3;*/
- //public static final byte[] mov_bx_ax = new byte[]{ (byte) 0x89, (byte) (mod_rm_bx | mod_reg_ax)}; // MOV r/m32, r32
- //public static final byte[] mov_ax_bx = new byte[]{ (byte) 0x89, (byte) (mod_rm_ax | mod_reg_bx)}; // MOV r/m32, r32
- //public static final byte[] mov_dx_ax = new byte[]{ (byte) 0x89, (byte) (mod_rm_dx | mod_reg_ax)}; // MOV r/m32, r32
- public static final byte[] mov_ax_dx = new byte[]{ (byte) 0x89, (byte) (mod_rm_ax | mod_reg_dx)}; // MOV r/m32, r32
- public static final byte[] xor_dx_dx = new byte[]{ (byte) 0x31, (byte) (mod_rm_dx | mod_reg_dx)}; // XOR r/m32, r32
- public static final byte[] cmp_ax_cx = new byte[]{ (byte) 0x39, (byte) (mod_rm_ax | mod_reg_cx)}; // CMP r/m32, r32
- public static final byte[] extract_bit1_ax = new byte[]{ (byte) 0x83, (byte) (mod_rm_ax | mod_op_4), (byte) 0x01}; // AND r/m32, i8 (0x01)
- public static final byte[] extract_bit1_cx = new byte[]{ (byte) 0x83, (byte) (mod_rm_cx | mod_op_4), (byte) 0x01}; // AND r/m32, i8 (0x01)
- public static final byte[] mov_s0_s1 = new byte[]{ (byte) 0xDD, (byte) 0xD0+1}; // FST (s1)
- public enum IntelOpcodeOperator {
- OP_INT_ADD_S,
- OP_INT_SUB_S,
- OP_INT_MUL_S,
- OP_INT_DIV_S,
- OP_INT_MOD_S,
- OP_INT_ADD_U,
- OP_INT_SUB_U,
- OP_INT_MUL_U,
- OP_INT_DIV_U,
- OP_INT_MOD_U,
- OP_INT_INC,
- OP_INT_DEC,
- OP_INT_NEGATE,
- OP_FLT_ADD,
- OP_FLT_SUB,
- OP_FLT_MUL,
- OP_FLT_DIV,
- OP_FLT_MOD,
- OP_FLT_NEGATE,
- OP_BIT_AND,
- OP_BIT_OR,
- OP_BIT_XOR,
- OP_BIT_COMPLEMENT,
- OP_BIT_SHR,
- OP_BIT_SHL,
- OP_BIT_SAR,
- OP_BIT_SAL,
- OP_BIT_ROR,
- OP_BIT_ROL,
- //OP_BIT_RCR,
- //OP_BIT_RCL,
- /*OP_LGC_AND, // use bitwise
- OP_LGC_OR,
- OP_LGC_XOR,*/
- OP_LGC_NOT,
- // TODO compare float
- OP_LGC_EQ, // return boolean
- OP_LGC_NEQ,
- OP_LGC_GT_S,
- OP_LGC_GTE_S,
- OP_LGC_LT_S,
- OP_LGC_LTE_S,
- OP_LGC_GT_U,
- OP_LGC_GTE_U,
- OP_LGC_LT_U,
- OP_LGC_LTE_U,
- }
- public enum IntelOpcodeSpecial {
- //OP_MOV,
- //OP_CMP, // only for OP_JMP_cond
- //OP_TEST, // conditional execution
- OP_JMP,
- // if / switch / for / while / break
- OP_JMP_IF_TRUE, // jmp, if ax != 0
- OP_JMP_IF_FALSE, // jmp, if ax == 0
- /*OP_CALL, // use return pointer at fixed address (fixed code)
- OP_RET,*/
- /*OP_JMP_EQ, // use calculation
- OP_JMP_NEQ,
- OP_JMP_GT_S,
- OP_JMP_GTE_S,
- OP_JMP_LT_S,
- OP_JMP_LTE_S,
- OP_JMP_GT_U,
- OP_JMP_GTE_U,
- OP_JMP_LT_U,
- OP_JMP_LTE_U,*/
- // finit, fwait, int, inbwd, outbwd
- // interrupt: iret, stack(push, pop)
- // task: sysenter/call/exit/leave
- OP_IRET,
- OP_INVALID_EXECUTE_LOCATION,
- }
- public enum IntelOpcodeSystem {
- OP_LIDT,
- OP_LGDT,
- }
- public static IntelInstruction[] getOpcodeOperator(IntelOpcodeOperator opcode) {
- // input: ax, cx
- // output: ax
- IntelInstruction instruction[] = new IntelInstruction[] {
- new IntelInstruction(),
- new IntelInstruction(),
- new IntelInstruction(),
- new IntelInstruction(),
- };
- switch(opcode) {
- case OP_INT_ADD_S:
- instruction[0].bytecode = new byte[]{ (byte) 0x11, (byte) (mod_rm_cx | mod_reg_ax)}; // ADC r/m32, r32
- break;
- case OP_INT_SUB_S:
- instruction[0].bytecode = new byte[]{ (byte) 0x19, (byte) (mod_rm_cx | mod_reg_ax)}; // SBB r/m32, r32
- break;
- case OP_INT_MUL_S:
- instruction[0].bytecode = new byte[]{ (byte) 0xF7, (byte) (mod_rm_cx | mod_op_4)}; // MUL r/m32, ax
- instruction[1].bytecode = xor_dx_dx;
- break;
- case OP_INT_DIV_S: // TODO negative operand
- instruction[0].bytecode = xor_dx_dx;
- instruction[1].bytecode = new byte[]{ (byte) 0xF7, (byte) (mod_rm_cx | mod_op_6)}; // DIV r/m32, dx:ax
- instruction[2].bytecode = xor_dx_dx;
- break;
- case OP_INT_MOD_S: // TODO negative operand
- instruction[0].bytecode = xor_dx_dx;
- instruction[1].bytecode = new byte[]{ (byte) 0xF7, (byte) (mod_rm_cx | mod_op_6)}; // DIV r/m32, dx:ax
- instruction[2].bytecode = mov_ax_dx;
- instruction[3].bytecode = xor_dx_dx;
- break;
- case OP_INT_ADD_U:
- instruction[0].bytecode = new byte[]{ (byte) 0x01, (byte) (mod_rm_cx | mod_reg_ax)}; // ADD r/m32, r32
- break;
- case OP_INT_SUB_U:
- instruction[0].bytecode = new byte[]{ (byte) 0x29, (byte) (mod_rm_cx | mod_reg_ax)}; // SUB r/m32, r32
- break;
- case OP_INT_MUL_U:
- instruction[0].bytecode = new byte[]{ (byte) 0xF7, (byte) (mod_rm_cx | mod_op_5)}; // IMUL r/m32, ax
- instruction[1].bytecode = xor_dx_dx;
- break;
- case OP_INT_DIV_U:
- instruction[0].bytecode = xor_dx_dx;
- instruction[1].bytecode = new byte[]{ (byte) 0xF7, (byte) (mod_rm_cx | mod_op_7)}; // IDIV r/m32, dx:ax
- instruction[2].bytecode = xor_dx_dx;
- break;
- case OP_INT_MOD_U:
- instruction[0].bytecode = xor_dx_dx;
- instruction[1].bytecode = new byte[]{ (byte) 0xF7, (byte) (mod_rm_cx | mod_op_7)}; // IDIV r/m32, dx:ax
- instruction[2].bytecode = mov_ax_dx;
- instruction[3].bytecode = xor_dx_dx;
- break;
- case OP_INT_INC:
- instruction[0].bytecode = new byte[]{ (byte) 0xFF, (byte) (mod_rm_ax | mod_op_0)}; // INC r/m32
- break;
- case OP_INT_DEC:
- instruction[0].bytecode = new byte[]{ (byte) 0xFF, (byte) (mod_rm_ax | mod_op_1)}; // DEC r/m32
- break;
- case OP_INT_NEGATE:
- instruction[0].bytecode = new byte[]{ (byte) 0xF7, (byte) (mod_rm_ax | mod_op_3)}; // NEG r/m32
- break;
- case OP_FLT_ADD:
- instruction[0].bytecode = new byte[]{ (byte) 0xD8, (byte) (0xC0 + 1)}; // FADD +i (s0, s1)
- break;
- case OP_FLT_SUB:
- instruction[0].bytecode = new byte[]{ (byte) 0xD8, (byte) (0xE0 + 1)}; // FSUB +i (s0, s1)
- break;
- case OP_FLT_MUL:
- instruction[0].bytecode = new byte[]{ (byte) 0xD8, (byte) (0xC8 + 1)}; // FMUL +i (s0, s1)
- break;
- case OP_FLT_DIV:
- instruction[0].bytecode = new byte[]{ (byte) 0xD8, (byte) (0xF0 + 1)}; // FDIV +i (s0, s1)
- break;
- case OP_FLT_MOD:
- instruction[0].bytecode = new byte[]{ (byte) 0xD9, (byte) 0xF5}; // FPREM1 (s0, s1)
- break;
- case OP_FLT_NEGATE:
- instruction[0].bytecode = new byte[]{ (byte) 0xD9, (byte) 0xE0}; // FCHS (s0)
- break;
- case OP_BIT_AND:
- instruction[0].bytecode = new byte[]{ (byte) 0x21, (byte) (mod_rm_cx | mod_reg_ax)}; // AND r/m32, r32
- break;
- case OP_BIT_OR:
- instruction[0].bytecode = new byte[]{ (byte) 0x09, (byte) (mod_rm_cx | mod_reg_ax)}; // OR r/m32, r32
- break;
- case OP_BIT_XOR:
- instruction[0].bytecode = new byte[]{ (byte) 0x31, (byte) (mod_rm_cx | mod_reg_ax)}; // XOR r/m32, r32
- break;
- case OP_BIT_COMPLEMENT:
- instruction[0].bytecode = new byte[]{ (byte) 0xF7, (byte) (mod_rm_ax | mod_op_2)}; // NOT r/m32
- break;
- case OP_BIT_SHR:
- instruction[0].bytecode = new byte[]{ (byte) 0xD3, (byte) (mod_rm_ax | mod_op_5)}; // SHR r/m32, cl
- break;
- case OP_BIT_SAR:
- instruction[0].bytecode = new byte[]{ (byte) 0xD3, (byte) (mod_rm_ax | mod_op_7)}; // SAR r/m32, cl
- break;
- case OP_BIT_SHL:
- case OP_BIT_SAL:
- instruction[0].bytecode = new byte[]{ (byte) 0xD3, (byte) (mod_rm_ax | mod_op_4)}; // SHL r/m32, cl
- break;
- case OP_BIT_ROR:
- instruction[0].bytecode = new byte[]{ (byte) 0xD3, (byte) (mod_rm_ax | mod_op_1)}; // ROR r/m32, cl
- break;
- case OP_BIT_ROL:
- instruction[0].bytecode = new byte[]{ (byte) 0xD3, (byte) (mod_rm_ax | mod_op_0)}; // ROL r/m32, cl
- break;
- /*case OP_LGC_AND:
- instruction[0].bytecode = new byte[]{ (byte) 0x, (byte) (mod_rm_cx | mod_reg_ax)}; // AND r/m8, r8
- break;
- case OP_LGC_OR:
- instruction[0].bytecode = new byte[]{ (byte) 0x, (byte) (mod_rm_cx | mod_reg_ax)}; // AND r/m8, r8
- break;
- case OP_LGC_XOR:
- instruction[0].bytecode = new byte[]{ (byte) 0x, (byte) (mod_rm_cx | mod_reg_ax)}; // AND r/m8, r8
- break;*/
- case OP_LGC_NOT:
- instruction[0].bytecode = new byte[]{ (byte) 0x80, (byte) (mod_rm_ax | mod_op_6), 1}; // XOR r/m8, i8
- break;
- case OP_LGC_EQ:// TODO use cmov
- instruction[0].bytecode = cmp_ax_cx;
- instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x94, (byte) (mod_rm_ax)}; // SETE r/m8
- instruction[2].bytecode = extract_bit1_ax;
- break;
- case OP_LGC_NEQ:
- instruction[0].bytecode = cmp_ax_cx;
- instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x95, (byte) (mod_rm_ax)}; // SETNE r/m8
- instruction[2].bytecode = extract_bit1_ax;
- break;
- case OP_LGC_GT_S:
- instruction[0].bytecode = cmp_ax_cx;
- instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x9F, (byte) (mod_rm_ax)}; // SETG r/m8
- instruction[2].bytecode = extract_bit1_ax;
- break;
- case OP_LGC_GTE_S:
- instruction[0].bytecode = cmp_ax_cx;
- instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x9D, (byte) (mod_rm_ax)}; // SETGE r/m8
- instruction[2].bytecode = extract_bit1_ax;
- break;
- case OP_LGC_LT_S:
- instruction[0].bytecode = cmp_ax_cx;
- instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x9C, (byte) (mod_rm_ax)}; // SETL r/m8
- instruction[2].bytecode = extract_bit1_ax;
- break;
- case OP_LGC_LTE_S:
- instruction[0].bytecode = cmp_ax_cx;
- instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x9E, (byte) (mod_rm_ax)}; // SETLE r/m8
- instruction[2].bytecode = extract_bit1_ax;
- break;
- case OP_LGC_GT_U:
- instruction[0].bytecode = cmp_ax_cx;
- instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x97, (byte) (mod_rm_ax)}; // SETA r/m8
- instruction[2].bytecode = extract_bit1_ax;
- break;
- case OP_LGC_GTE_U:
- instruction[0].bytecode = cmp_ax_cx;
- instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x93, (byte) (mod_rm_ax)}; // SETAE r/m8
- instruction[2].bytecode = extract_bit1_ax;
- break;
- case OP_LGC_LT_U:
- instruction[0].bytecode = cmp_ax_cx;
- instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x92, (byte) (mod_rm_ax)}; // SETB r/m8
- instruction[2].bytecode = extract_bit1_ax;
- break;
- case OP_LGC_LTE_U:
- instruction[0].bytecode = cmp_ax_cx;
- instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x96, (byte) (mod_rm_ax)}; // SETBE r/m8
- instruction[2].bytecode = extract_bit1_ax;
- break;
- default: assert false;
- }
- return instruction;
- }
- public static IntelInstruction[] getOpcodeSpecial(IntelOpcodeSpecial opcode) {
- IntelInstruction instruction[] = new IntelInstruction[] {
- new IntelInstruction(),
- new IntelInstruction(),
- new IntelInstruction(),
- new IntelInstruction(),
- };
- switch(opcode) {
- case OP_JMP:// TODO: load bx
- instruction[0].bytecode = new byte[]{ (byte) 0xFF, (byte) (mod_rm_bx | mod_op_4)}; // JMP r/m32
- break;
- case OP_JMP_IF_TRUE:
- instruction[0].bytecode = new byte[]{ (byte) 0x09, (byte) (mod_rm_ax | mod_reg_ax)}; // OR r/m32, r32
- instruction[1].bytecode = new byte[]{ (byte) 0x74, (byte) 0x02}; // JZ rel8 (2)
- instruction[2].bytecode = new byte[]{ (byte) 0xFF, (byte) (mod_rm_bx | mod_op_4)}; // JMP r/m32
- break;
- case OP_JMP_IF_FALSE:
- instruction[0].bytecode = new byte[]{ (byte) 0x09, (byte) (mod_rm_ax | mod_reg_ax)}; // OR r/m32, r32
- instruction[1].bytecode = new byte[]{ (byte) 0x75, (byte) 0x02}; // JNZ rel8 (2)
- instruction[2].bytecode = new byte[]{ (byte) 0xFF, (byte) (mod_rm_bx | mod_op_4)}; // JMP r/m32
- break;
- case OP_IRET:
- instruction[0].bytecode = new byte[]{ (byte) 0xCF}; // IRET
- break;
- case OP_INVALID_EXECUTE_LOCATION: // TODO: triple fault, reset
- instruction[0].bytecode = new byte[]{ (byte) 0x90, (byte) 0x90, (byte) 0x90, (byte) 0x90}; // NOPs
- instruction[1].bytecode = new byte[]{ (byte) 0xCD, (byte) 0x08}; // INT i8 (8), double fault
- instruction[2].bytecode = new byte[]{ (byte) 0xF4}; // HLT
- instruction[3].bytecode = new byte[]{ (byte) 0xEB, (byte) 0xFB}; // JMP rel8 (-5)
- break;
- default: assert false;
- }
- return instruction;
- }
- /*public static IntelInstruction[] getOpcodeSystem(IntelOpcodeSystem opcode) {
- IntelInstruction instruction[] = new IntelInstruction[] {
- new IntelInstruction(),
- new IntelInstruction(),
- new IntelInstruction(),
- };
- switch(opcode) {
- default: assert false;
- }
- return instruction;
- }*/
- public static IntelInstruction[] loadInteger(int sel_reg) {
- // input: mem (bx)
- // output: ax, cx
- IntelInstruction instruction[] = new IntelInstruction[] {
- new IntelInstruction(),
- };
- switch(sel_reg) {
- case sel_ax:
- instruction[0].bytecode = new byte[]{ (byte) 0x8B, (byte) (mod_reg_ax | mod_rm_bx_p)}; // MOV r32, r/m32
- break;
- case sel_cx:
- instruction[0].bytecode = new byte[]{ (byte) 0x8B, (byte) (mod_reg_cx | mod_rm_bx_p)}; // MOV r32, r/m32
- break;
- default: assert false;
- }
- return instruction;
- }
- public static IntelInstruction[] storeInteger() {
- // input: ax
- // output: mem (bx)
- IntelInstruction instruction[] = new IntelInstruction[] {
- new IntelInstruction(),
- };
- instruction[0].bytecode = new byte[]{ (byte) 0x89, (byte) (mod_rm_bx_p | mod_reg_ax)}; // MOV r/m32, r32
- return instruction;
- }
- public static IntelInstruction[] loadFloat(int sel_reg, boolean integer) {
- // input: mem (bx)
- // output: s0, s1
- IntelInstruction instruction[] = new IntelInstruction[] {
- new IntelInstruction(),
- new IntelInstruction(),
- };
- if(integer)
- instruction[0].bytecode = new byte[]{ (byte) 0xDB, (byte) (mod_rm_bx_p | mod_op_0)}; // FILD m32i
- else
- instruction[0].bytecode = new byte[]{ (byte) 0xDB, (byte) (mod_rm_bx_p | mod_op_5)}; // FLD m80f
- switch(sel_reg) {
- case 0:
- break;
- case 1:
- instruction[1].bytecode = mov_s0_s1;
- break;
- default: assert false;
- }
- return instruction;
- }
- public static IntelInstruction[] storeFloat(boolean integer) {
- // input: s0
- // output: mem (bx)
- IntelInstruction instruction[] = new IntelInstruction[] {
- new IntelInstruction(),
- new IntelInstruction(),
- };
- if(integer) {
- instruction[0].bytecode = new byte[]{ (byte) 0xDB, (byte) (mod_rm_bx_p | mod_op_2)}; // FIST m32i
- }
- else {
- instruction[0].bytecode = new byte[]{ (byte) 0xDB, (byte) (mod_rm_bx_p | mod_op_7)}; // FSTP m80f
- instruction[1].bytecode = mov_s0_s1;
- }
- return instruction;
- }
- public static IntelInstruction[] castIntegerBoolean(int sel_reg) {
- // input: 0:ax 1:bx
- // output: 0 if == 0 otherwise 1
- IntelInstruction instruction[] = new IntelInstruction[] {
- new IntelInstruction(),
- new IntelInstruction(),
- new IntelInstruction(),
- };
- switch(sel_reg) {// TODO use XOR
- case sel_ax:
- instruction[0].bytecode = new byte[]{ (byte) 0x09, (byte) (mod_rm_ax | mod_reg_ax)}; // OR r/m32, r32
- instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x95, (byte) (mod_rm_ax)}; // SETNZ r/m8
- instruction[2].bytecode = extract_bit1_ax;
- break;
- case sel_cx:
- instruction[0].bytecode = new byte[]{ (byte) 0x09, (byte) (mod_rm_cx | mod_reg_cx)}; // OR r/m32, r32
- instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x95, (byte) (mod_rm_cx)}; // SETNZ r/m8
- instruction[2].bytecode = extract_bit1_cx;
- break;
- default: assert false;
- }
- return instruction;
- }
- public static IntelInstruction[] loadAddress(int physicalAddress) {
- // output: bx
- IntelInstruction instruction[] = new IntelInstruction[] {
- new IntelInstruction(),
- };
- byte[] b = new byte[]{
- (byte) ((physicalAddress & 0x000000FF) >>> 0),
- (byte) ((physicalAddress & 0x0000FF00) >>> 8),
- (byte) ((physicalAddress & 0x00FF0000) >>> 16),
- (byte) ((physicalAddress & 0xFF000000) >>> 24),
- };
- instruction[0].bytecode = new byte[]{ (byte) (0xB8 + add_bx), b[0], b[1], b[2], b[3]}; // MOV r32, i32
- return instruction;
- }
- public static IntelInstruction[] loadJumpAddress(BytecodeOffset[] offset) {
- // output: bx
- IntelInstruction instruction[] = new IntelInstruction[] {
- new IntelInstruction(),
- };
- instruction[0].bytecode = new byte[]{ (byte) (0xB8 + add_bx), 0, 0, 0, 0}; // MOV r32, i32
- assert instruction[0].bytecode.length == 5;
- instruction[0].locate = true;
- instruction[0].offset = offset;
- return instruction;
- }
- public static IntelInstruction[] loadIntegerConstant(int sel_reg, int constant) {
- // output: ax
- IntelInstruction instruction[] = new IntelInstruction[] {
- new IntelInstruction(),
- };
- byte[] b = new byte[]{
- (byte) ((constant & 0x000000FF) >>> 0),
- (byte) ((constant & 0x0000FF00) >>> 8),
- (byte) ((constant & 0x00FF0000) >>> 16),
- (byte) ((constant & 0xFF000000) >>> 24),
- };
- switch(sel_reg) {
- case sel_ax:
- instruction[0].bytecode = new byte[]{ (byte) (0xB8 + add_ax), b[0], b[1], b[2], b[3]}; // MOV r32, i32
- break;
- case sel_cx:
- instruction[0].bytecode = new byte[]{ (byte) (0xB8 + add_cx), b[0], b[1], b[2], b[3]}; // MOV r32, i32
- break;
- default: assert false;
- }
- return instruction;
- }
- public static IntelInstruction[] storeIntegerConstant(int constant) {
- // output: mem (bx)
- IntelInstruction instruction[] = new IntelInstruction[] {
- new IntelInstruction(),
- };
- byte[] b = new byte[]{
- (byte) ((constant & 0x000000FF) >>> 0),
- (byte) ((constant & 0x0000FF00) >>> 8),
- (byte) ((constant & 0x00FF0000) >>> 16),
- (byte) ((constant & 0xFF000000) >>> 24),
- };
- instruction[0].bytecode = new byte[]{ (byte) 0xC7, (byte) (mod_rm_bx_p | mod_op_0), b[0], b[1], b[2], b[3]}; // MOV r/m32, i32
- return instruction;
- }
- /*public static IntelInstruction[] loadInterruptDescriptorTable() {
- IntelInstruction instruction[] = new IntelInstruction[] {
- new IntelInstruction(),
- };
- instruction[0].bytecode = new byte[]{ (byte) 0x00}; // LIDT
- return instruction;
- }
- public static IntelInstruction[] loadGlobalDescriptorTable() {
- IntelInstruction instruction[] = new IntelInstruction[] {
- new IntelInstruction(),
- };
- instruction[0].bytecode = new byte[]{ (byte) 0x00}; // LIDT
- return instruction;
- }
- public static IntelInstruction[] loadLocalDescriptorTable() {
- IntelInstruction instruction[] = new IntelInstruction[] {
- new IntelInstruction(),
- };
- instruction[0].bytecode = new byte[]{ (byte) 0x00}; // LIDT
- return instruction;
- }
- public static IntelInstruction[] loadTaskStateSegment() {
- IntelInstruction instruction[] = new IntelInstruction[] {
- new IntelInstruction(),
- };
- instruction[0].bytecode = new byte[]{ (byte) 0x00}; // LIDT
- return instruction;
- }*/
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement