Advertisement
Dimension

ExportOpcode.java

Dec 26th, 2011
42
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 21.85 KB | None | 0 0
  1. package emulator.editor;
  2.  
  3. import java.nio.*;
  4. import java.util.Vector;
  5.  
  6. import emulator.code.Operation.OperationType;
  7. import emulator.code.Operation.OperationType.IExecuteExpression;
  8. import emulator.editor.Export.BytecodeOffset;
  9. import emulator.editor.Export.IntelInstruction;
  10.  
  11. public class ExportOpcode {
  12.     // all 32 bit int, 80 bit float
  13.     // calculate ax, cx
  14.     // address: bx
  15.     // port/string: dx
  16.     // move ax to cx
  17.     // condition: test
  18.     // logic compare: cmp
  19.  
  20.     // opt: prefix (1b)
  21.     // opcode (2-3b)
  22.     // opt: modr/m (1b)
  23.     // opt: sib (1b) TODO use for fixed size array pages
  24.     // opt: disp/const (1-4b)
  25.    
  26.     // TODO list and deassemble all opcodes & check
  27.     // use tmp registers, fpu stack
  28.  
  29.     // provide access:
  30.     // segment register, task register, ldtr, tss, gdtr, idtr
  31.     // stack pointer
  32.     // flag register read
  33.     // cr0-4, dr0-7
  34.    
  35.     // provide opcodes:
  36.     // lea, lmsw, smsw, rdpmc, rdtsc, cpuid
  37.     // int/float byte size conversion (cbw, ..., movsx/zx)
  38.     // std, cld, sti, cli
  39.     // rep (dma?), string, port
  40.  
  41.     // TODO: ask: register, opcodes, stack (interrupt), ldtr, tss, physical address bx, call gate
  42.    
  43.     // TODO SETx insert leading XOR (8bit -> 32bit)
  44.    
  45.     /*public static final byte mod_rm_ax_p = (byte) Integer.parseInt("00000000", 2);
  46.     public static final byte mod_rm_cx_p = (byte) Integer.parseInt("00000001", 2);
  47.     public static final byte mod_rm_dx_p = (byte) Integer.parseInt("00000010", 2);*/
  48.     public static final byte mod_rm_bx_p = (byte) Integer.parseInt("00000011", 2);
  49.    
  50.     public static final byte mod_rm_ax = (byte) Integer.parseInt("11000000", 2);
  51.     public static final byte mod_rm_cx = (byte) Integer.parseInt("11000001", 2);
  52.     public static final byte mod_rm_dx = (byte) Integer.parseInt("11000010", 2);
  53.     public static final byte mod_rm_bx = (byte) Integer.parseInt("11000011", 2);
  54.     /*public static final byte mod_rm_sp = (byte) Integer.parseInt("11000100", 2);
  55.     public static final byte mod_rm_bp = (byte) Integer.parseInt("11000101", 2);
  56.     public static final byte mod_rm_si = (byte) Integer.parseInt("11000110", 2);
  57.     public static final byte mod_rm_di = (byte) Integer.parseInt("11000111", 2);*/
  58.  
  59.     public static final byte mod_op_0 = (byte) Integer.parseInt("00000000", 2);
  60.     public static final byte mod_op_1 = (byte) Integer.parseInt("00001000", 2);
  61.     public static final byte mod_op_2 = (byte) Integer.parseInt("00010000", 2);
  62.     public static final byte mod_op_3 = (byte) Integer.parseInt("00011000", 2);
  63.     public static final byte mod_op_4 = (byte) Integer.parseInt("00100000", 2);
  64.     public static final byte mod_op_5 = (byte) Integer.parseInt("00101000", 2);
  65.     public static final byte mod_op_6 = (byte) Integer.parseInt("00110000", 2);
  66.     public static final byte mod_op_7 = (byte) Integer.parseInt("00111000", 2);
  67.  
  68.     public static final byte mod_reg_ax = mod_op_0;
  69.     public static final byte mod_reg_cx = mod_op_1;
  70.     public static final byte mod_reg_dx = mod_op_2;
  71.     public static final byte mod_reg_bx = mod_op_3;
  72.     /*public static final byte mod_reg_sp = mod_op_4;
  73.     public static final byte mod_reg_bp = mod_op_5;
  74.     public static final byte mod_reg_si = mod_op_6;
  75.     public static final byte mod_reg_di = mod_op_7;*/
  76.  
  77.     public static final byte add_ax = 0;
  78.     public static final byte add_cx = 1;
  79.     public static final byte add_dx = 2;
  80.     public static final byte add_bx = 3;
  81.     /*public static final byte add_sp = 4;
  82.     public static final byte add_bp = 5;
  83.     public static final byte add_si = 6;
  84.     public static final byte add_di = 7;*/
  85.    
  86.     public static final byte sel_ax = 0;
  87.     public static final byte sel_cx = 1;
  88.     /*public static final byte sel_dx = 2;
  89.     public static final byte sel_bx = 3;*/
  90.  
  91.     //public static final byte[] mov_bx_ax = new byte[]{ (byte) 0x89, (byte) (mod_rm_bx | mod_reg_ax)}; // MOV r/m32, r32
  92.     //public static final byte[] mov_ax_bx = new byte[]{ (byte) 0x89, (byte) (mod_rm_ax | mod_reg_bx)}; // MOV r/m32, r32
  93.     //public static final byte[] mov_dx_ax = new byte[]{ (byte) 0x89, (byte) (mod_rm_dx | mod_reg_ax)}; // MOV r/m32, r32
  94.     public static final byte[] mov_ax_dx = new byte[]{ (byte) 0x89, (byte) (mod_rm_ax | mod_reg_dx)}; // MOV r/m32, r32
  95.    
  96.     public static final byte[] xor_dx_dx = new byte[]{ (byte) 0x31, (byte) (mod_rm_dx | mod_reg_dx)}; // XOR r/m32, r32
  97.     public static final byte[] cmp_ax_cx = new byte[]{ (byte) 0x39, (byte) (mod_rm_ax | mod_reg_cx)}; // CMP r/m32, r32
  98.     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)
  99.     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)
  100.  
  101.     public static final byte[] mov_s0_s1 = new byte[]{ (byte) 0xDD, (byte) 0xD0+1}; // FST (s1)
  102.    
  103.     public enum IntelOpcodeOperator {
  104.         OP_INT_ADD_S,
  105.         OP_INT_SUB_S,
  106.         OP_INT_MUL_S,
  107.         OP_INT_DIV_S,
  108.         OP_INT_MOD_S,
  109.  
  110.         OP_INT_ADD_U,
  111.         OP_INT_SUB_U,
  112.         OP_INT_MUL_U,
  113.         OP_INT_DIV_U,
  114.         OP_INT_MOD_U,
  115.        
  116.         OP_INT_INC,
  117.         OP_INT_DEC,
  118.         OP_INT_NEGATE,
  119.        
  120.         OP_FLT_ADD,
  121.         OP_FLT_SUB,
  122.         OP_FLT_MUL,
  123.         OP_FLT_DIV,
  124.         OP_FLT_MOD,
  125.         OP_FLT_NEGATE,
  126.        
  127.         OP_BIT_AND,
  128.         OP_BIT_OR,
  129.         OP_BIT_XOR,
  130.         OP_BIT_COMPLEMENT,
  131.         OP_BIT_SHR,
  132.         OP_BIT_SHL,
  133.         OP_BIT_SAR,
  134.         OP_BIT_SAL,
  135.         OP_BIT_ROR,
  136.         OP_BIT_ROL,
  137.         //OP_BIT_RCR,
  138.         //OP_BIT_RCL,
  139.        
  140.         /*OP_LGC_AND, // use bitwise
  141.         OP_LGC_OR,
  142.         OP_LGC_XOR,*/
  143.         OP_LGC_NOT,
  144.        
  145.         // TODO compare float
  146.         OP_LGC_EQ, // return boolean
  147.         OP_LGC_NEQ,
  148.         OP_LGC_GT_S,
  149.         OP_LGC_GTE_S,
  150.         OP_LGC_LT_S,
  151.         OP_LGC_LTE_S,
  152.         OP_LGC_GT_U,
  153.         OP_LGC_GTE_U,
  154.         OP_LGC_LT_U,
  155.         OP_LGC_LTE_U,
  156.     }
  157.  
  158.     public enum IntelOpcodeSpecial {
  159.         //OP_MOV,
  160.         //OP_CMP, // only for OP_JMP_cond
  161.         //OP_TEST, // conditional execution
  162.         OP_JMP,
  163.         // if / switch / for / while / break
  164.         OP_JMP_IF_TRUE, // jmp, if ax != 0
  165.         OP_JMP_IF_FALSE, // jmp, if ax == 0
  166.  
  167.         /*OP_CALL, // use return pointer at fixed address (fixed code)
  168.         OP_RET,*/
  169.        
  170.         /*OP_JMP_EQ, // use calculation
  171.         OP_JMP_NEQ,
  172.         OP_JMP_GT_S,
  173.         OP_JMP_GTE_S,
  174.         OP_JMP_LT_S,
  175.         OP_JMP_LTE_S,
  176.         OP_JMP_GT_U,
  177.         OP_JMP_GTE_U,
  178.         OP_JMP_LT_U,
  179.         OP_JMP_LTE_U,*/
  180.        
  181.         // finit, fwait, int, inbwd, outbwd
  182.         // interrupt: iret, stack(push, pop)
  183.         // task: sysenter/call/exit/leave
  184.  
  185.         OP_IRET,
  186.         OP_INVALID_EXECUTE_LOCATION,
  187.     }
  188.  
  189.     public enum IntelOpcodeSystem {
  190.         OP_LIDT,
  191.         OP_LGDT,
  192.     }
  193.    
  194.     public static IntelInstruction[] getOpcodeOperator(IntelOpcodeOperator opcode) {
  195.         // input: ax, cx
  196.         // output: ax
  197.        
  198.         IntelInstruction instruction[] = new IntelInstruction[] {
  199.                 new IntelInstruction(),
  200.                 new IntelInstruction(),
  201.                 new IntelInstruction(),
  202.                 new IntelInstruction(),
  203.         };
  204.        
  205.         switch(opcode) {
  206.         case OP_INT_ADD_S:
  207.             instruction[0].bytecode = new byte[]{ (byte) 0x11, (byte) (mod_rm_cx | mod_reg_ax)}; // ADC r/m32, r32
  208.             break;
  209.         case OP_INT_SUB_S:
  210.             instruction[0].bytecode = new byte[]{ (byte) 0x19, (byte) (mod_rm_cx | mod_reg_ax)}; // SBB r/m32, r32
  211.             break;
  212.         case OP_INT_MUL_S:
  213.             instruction[0].bytecode = new byte[]{ (byte) 0xF7, (byte) (mod_rm_cx | mod_op_4)}; // MUL r/m32, ax
  214.             instruction[1].bytecode = xor_dx_dx;
  215.             break;
  216.         case OP_INT_DIV_S: // TODO negative operand
  217.             instruction[0].bytecode = xor_dx_dx;
  218.             instruction[1].bytecode = new byte[]{ (byte) 0xF7, (byte) (mod_rm_cx | mod_op_6)}; // DIV r/m32, dx:ax
  219.             instruction[2].bytecode = xor_dx_dx;
  220.             break;
  221.         case OP_INT_MOD_S: // TODO negative operand
  222.             instruction[0].bytecode = xor_dx_dx;
  223.             instruction[1].bytecode = new byte[]{ (byte) 0xF7, (byte) (mod_rm_cx | mod_op_6)}; // DIV r/m32, dx:ax
  224.             instruction[2].bytecode = mov_ax_dx;
  225.             instruction[3].bytecode = xor_dx_dx;
  226.             break;
  227.         case OP_INT_ADD_U:
  228.             instruction[0].bytecode = new byte[]{ (byte) 0x01, (byte) (mod_rm_cx | mod_reg_ax)}; // ADD r/m32, r32
  229.             break;
  230.         case OP_INT_SUB_U:
  231.             instruction[0].bytecode = new byte[]{ (byte) 0x29, (byte) (mod_rm_cx | mod_reg_ax)}; // SUB r/m32, r32
  232.             break;
  233.         case OP_INT_MUL_U:
  234.             instruction[0].bytecode = new byte[]{ (byte) 0xF7, (byte) (mod_rm_cx | mod_op_5)}; // IMUL r/m32, ax
  235.             instruction[1].bytecode = xor_dx_dx;
  236.             break;
  237.         case OP_INT_DIV_U:
  238.             instruction[0].bytecode = xor_dx_dx;
  239.             instruction[1].bytecode = new byte[]{ (byte) 0xF7, (byte) (mod_rm_cx | mod_op_7)}; // IDIV r/m32, dx:ax
  240.             instruction[2].bytecode = xor_dx_dx;
  241.             break;
  242.         case OP_INT_MOD_U:
  243.             instruction[0].bytecode = xor_dx_dx;
  244.             instruction[1].bytecode = new byte[]{ (byte) 0xF7, (byte) (mod_rm_cx | mod_op_7)}; // IDIV r/m32, dx:ax
  245.             instruction[2].bytecode = mov_ax_dx;
  246.             instruction[3].bytecode = xor_dx_dx;
  247.             break;
  248.         case OP_INT_INC:
  249.             instruction[0].bytecode = new byte[]{ (byte) 0xFF, (byte) (mod_rm_ax | mod_op_0)}; // INC r/m32
  250.             break;
  251.         case OP_INT_DEC:
  252.             instruction[0].bytecode = new byte[]{ (byte) 0xFF, (byte) (mod_rm_ax | mod_op_1)}; // DEC r/m32
  253.             break;
  254.         case OP_INT_NEGATE:
  255.             instruction[0].bytecode = new byte[]{ (byte) 0xF7, (byte) (mod_rm_ax | mod_op_3)}; // NEG r/m32
  256.             break;
  257.            
  258.         case OP_FLT_ADD:
  259.             instruction[0].bytecode = new byte[]{ (byte) 0xD8, (byte) (0xC0 + 1)}; // FADD +i (s0, s1)
  260.             break;
  261.         case OP_FLT_SUB:
  262.             instruction[0].bytecode = new byte[]{ (byte) 0xD8, (byte) (0xE0 + 1)}; // FSUB +i (s0, s1)
  263.             break;
  264.         case OP_FLT_MUL:
  265.             instruction[0].bytecode = new byte[]{ (byte) 0xD8, (byte) (0xC8 + 1)}; // FMUL +i (s0, s1)
  266.             break;
  267.         case OP_FLT_DIV:
  268.             instruction[0].bytecode = new byte[]{ (byte) 0xD8, (byte) (0xF0 + 1)}; // FDIV +i (s0, s1)
  269.             break;
  270.         case OP_FLT_MOD:
  271.             instruction[0].bytecode = new byte[]{ (byte) 0xD9, (byte) 0xF5}; // FPREM1 (s0, s1)
  272.             break;
  273.         case OP_FLT_NEGATE:
  274.             instruction[0].bytecode = new byte[]{ (byte) 0xD9, (byte) 0xE0}; // FCHS (s0)
  275.             break;
  276.            
  277.         case OP_BIT_AND:
  278.             instruction[0].bytecode = new byte[]{ (byte) 0x21, (byte) (mod_rm_cx | mod_reg_ax)}; // AND r/m32, r32
  279.             break;
  280.         case OP_BIT_OR:
  281.             instruction[0].bytecode = new byte[]{ (byte) 0x09, (byte) (mod_rm_cx | mod_reg_ax)}; // OR r/m32, r32
  282.             break;
  283.         case OP_BIT_XOR:
  284.             instruction[0].bytecode = new byte[]{ (byte) 0x31, (byte) (mod_rm_cx | mod_reg_ax)}; // XOR r/m32, r32
  285.             break;
  286.         case OP_BIT_COMPLEMENT:
  287.             instruction[0].bytecode = new byte[]{ (byte) 0xF7, (byte) (mod_rm_ax | mod_op_2)}; // NOT r/m32
  288.             break;
  289.         case OP_BIT_SHR:
  290.             instruction[0].bytecode = new byte[]{ (byte) 0xD3, (byte) (mod_rm_ax | mod_op_5)}; // SHR r/m32, cl
  291.             break;
  292.         case OP_BIT_SAR:
  293.             instruction[0].bytecode = new byte[]{ (byte) 0xD3, (byte) (mod_rm_ax | mod_op_7)}; // SAR r/m32, cl
  294.             break;
  295.         case OP_BIT_SHL:
  296.         case OP_BIT_SAL:
  297.             instruction[0].bytecode = new byte[]{ (byte) 0xD3, (byte) (mod_rm_ax | mod_op_4)}; // SHL r/m32, cl
  298.             break;
  299.         case OP_BIT_ROR:
  300.             instruction[0].bytecode = new byte[]{ (byte) 0xD3, (byte) (mod_rm_ax | mod_op_1)}; // ROR r/m32, cl
  301.             break;
  302.         case OP_BIT_ROL:
  303.             instruction[0].bytecode = new byte[]{ (byte) 0xD3, (byte) (mod_rm_ax | mod_op_0)}; // ROL r/m32, cl
  304.             break;
  305.            
  306.         /*case OP_LGC_AND:
  307.             instruction[0].bytecode = new byte[]{ (byte) 0x, (byte) (mod_rm_cx | mod_reg_ax)}; // AND r/m8, r8
  308.             break;
  309.         case OP_LGC_OR:
  310.             instruction[0].bytecode = new byte[]{ (byte) 0x, (byte) (mod_rm_cx | mod_reg_ax)}; // AND r/m8, r8
  311.             break;
  312.         case OP_LGC_XOR:
  313.             instruction[0].bytecode = new byte[]{ (byte) 0x, (byte) (mod_rm_cx | mod_reg_ax)}; // AND r/m8, r8
  314.             break;*/
  315.         case OP_LGC_NOT:
  316.             instruction[0].bytecode = new byte[]{ (byte) 0x80, (byte) (mod_rm_ax | mod_op_6), 1}; // XOR r/m8, i8
  317.             break;
  318.            
  319.         case OP_LGC_EQ:// TODO use cmov
  320.             instruction[0].bytecode = cmp_ax_cx;
  321.             instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x94, (byte) (mod_rm_ax)}; // SETE r/m8
  322.             instruction[2].bytecode = extract_bit1_ax;
  323.             break;
  324.         case OP_LGC_NEQ:
  325.             instruction[0].bytecode = cmp_ax_cx;
  326.             instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x95, (byte) (mod_rm_ax)}; // SETNE r/m8
  327.             instruction[2].bytecode = extract_bit1_ax;
  328.             break;
  329.         case OP_LGC_GT_S:
  330.             instruction[0].bytecode = cmp_ax_cx;
  331.             instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x9F, (byte) (mod_rm_ax)}; // SETG r/m8
  332.             instruction[2].bytecode = extract_bit1_ax;
  333.             break;
  334.         case OP_LGC_GTE_S:
  335.             instruction[0].bytecode = cmp_ax_cx;
  336.             instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x9D, (byte) (mod_rm_ax)}; // SETGE r/m8
  337.             instruction[2].bytecode = extract_bit1_ax;
  338.             break;
  339.         case OP_LGC_LT_S:
  340.             instruction[0].bytecode = cmp_ax_cx;
  341.             instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x9C, (byte) (mod_rm_ax)}; // SETL r/m8
  342.             instruction[2].bytecode = extract_bit1_ax;
  343.             break;
  344.         case OP_LGC_LTE_S:
  345.             instruction[0].bytecode = cmp_ax_cx;
  346.             instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x9E, (byte) (mod_rm_ax)}; // SETLE r/m8
  347.             instruction[2].bytecode = extract_bit1_ax;
  348.             break;
  349.         case OP_LGC_GT_U:
  350.             instruction[0].bytecode = cmp_ax_cx;
  351.             instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x97, (byte) (mod_rm_ax)}; // SETA r/m8
  352.             instruction[2].bytecode = extract_bit1_ax;
  353.             break;
  354.         case OP_LGC_GTE_U:
  355.             instruction[0].bytecode = cmp_ax_cx;
  356.             instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x93, (byte) (mod_rm_ax)}; // SETAE r/m8
  357.             instruction[2].bytecode = extract_bit1_ax;
  358.             break;
  359.         case OP_LGC_LT_U:
  360.             instruction[0].bytecode = cmp_ax_cx;
  361.             instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x92, (byte) (mod_rm_ax)}; // SETB r/m8
  362.             instruction[2].bytecode = extract_bit1_ax;
  363.             break;
  364.         case OP_LGC_LTE_U:
  365.             instruction[0].bytecode = cmp_ax_cx;
  366.             instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x96, (byte) (mod_rm_ax)}; // SETBE r/m8
  367.             instruction[2].bytecode = extract_bit1_ax;
  368.             break;
  369.         default: assert false;
  370.         }
  371.        
  372.         return instruction;
  373.     }
  374.    
  375.     public static IntelInstruction[] getOpcodeSpecial(IntelOpcodeSpecial opcode) {     
  376.         IntelInstruction instruction[] = new IntelInstruction[] {
  377.                 new IntelInstruction(),
  378.                 new IntelInstruction(),
  379.                 new IntelInstruction(),
  380.                 new IntelInstruction(),
  381.         };
  382.        
  383.         switch(opcode) {
  384.         case OP_JMP:// TODO: load bx
  385.             instruction[0].bytecode = new byte[]{ (byte) 0xFF, (byte) (mod_rm_bx | mod_op_4)}; // JMP r/m32
  386.             break;
  387.         case OP_JMP_IF_TRUE:
  388.             instruction[0].bytecode = new byte[]{ (byte) 0x09, (byte) (mod_rm_ax | mod_reg_ax)}; // OR r/m32, r32
  389.             instruction[1].bytecode = new byte[]{ (byte) 0x74, (byte) 0x02}; // JZ rel8 (2)
  390.             instruction[2].bytecode = new byte[]{ (byte) 0xFF, (byte) (mod_rm_bx | mod_op_4)}; // JMP r/m32
  391.             break;
  392.         case OP_JMP_IF_FALSE:
  393.             instruction[0].bytecode = new byte[]{ (byte) 0x09, (byte) (mod_rm_ax | mod_reg_ax)}; // OR r/m32, r32
  394.             instruction[1].bytecode = new byte[]{ (byte) 0x75, (byte) 0x02}; // JNZ rel8 (2)
  395.             instruction[2].bytecode = new byte[]{ (byte) 0xFF, (byte) (mod_rm_bx | mod_op_4)}; // JMP r/m32
  396.             break;
  397.         case OP_IRET:
  398.             instruction[0].bytecode = new byte[]{ (byte) 0xCF}; // IRET
  399.             break;
  400.         case OP_INVALID_EXECUTE_LOCATION: // TODO: triple fault, reset
  401.             instruction[0].bytecode = new byte[]{ (byte) 0x90, (byte) 0x90, (byte) 0x90, (byte) 0x90}; // NOPs
  402.             instruction[1].bytecode = new byte[]{ (byte) 0xCD, (byte) 0x08}; // INT i8 (8), double fault
  403.             instruction[2].bytecode = new byte[]{ (byte) 0xF4}; // HLT
  404.             instruction[3].bytecode = new byte[]{ (byte) 0xEB, (byte) 0xFB}; // JMP rel8 (-5)
  405.             break;
  406.         default: assert false;
  407.         }
  408.        
  409.         return instruction;
  410.     }
  411.    
  412.     /*public static IntelInstruction[] getOpcodeSystem(IntelOpcodeSystem opcode) {     
  413.         IntelInstruction instruction[] = new IntelInstruction[] {
  414.                 new IntelInstruction(),
  415.                 new IntelInstruction(),
  416.                 new IntelInstruction(),
  417.         };
  418.        
  419.         switch(opcode) {
  420.         default: assert false;
  421.         }
  422.        
  423.         return instruction;
  424.     }*/
  425.    
  426.     public static IntelInstruction[] loadInteger(int sel_reg) {
  427.         // input: mem (bx)
  428.         // output: ax, cx
  429.        
  430.         IntelInstruction instruction[] = new IntelInstruction[] {
  431.                 new IntelInstruction(),
  432.         };
  433.        
  434.         switch(sel_reg) {
  435.         case sel_ax:
  436.             instruction[0].bytecode = new byte[]{ (byte) 0x8B, (byte) (mod_reg_ax | mod_rm_bx_p)}; // MOV r32, r/m32
  437.             break;
  438.         case sel_cx:
  439.             instruction[0].bytecode = new byte[]{ (byte) 0x8B, (byte) (mod_reg_cx | mod_rm_bx_p)}; // MOV r32, r/m32
  440.             break;
  441.         default: assert false;
  442.         }
  443.        
  444.         return instruction;
  445.     }
  446.    
  447.     public static IntelInstruction[] storeInteger() {
  448.         // input: ax
  449.         // output: mem (bx)
  450.        
  451.         IntelInstruction instruction[] = new IntelInstruction[] {
  452.                 new IntelInstruction(),
  453.         };
  454.        
  455.         instruction[0].bytecode = new byte[]{ (byte) 0x89, (byte) (mod_rm_bx_p | mod_reg_ax)}; // MOV r/m32, r32
  456.        
  457.         return instruction;
  458.     }
  459.    
  460.     public static IntelInstruction[] loadFloat(int sel_reg, boolean integer) {
  461.         // input: mem (bx)
  462.         // output: s0, s1
  463.        
  464.         IntelInstruction instruction[] = new IntelInstruction[] {
  465.                 new IntelInstruction(),
  466.                 new IntelInstruction(),
  467.         };
  468.  
  469.         if(integer)
  470.             instruction[0].bytecode = new byte[]{ (byte) 0xDB, (byte) (mod_rm_bx_p | mod_op_0)}; // FILD m32i
  471.         else
  472.             instruction[0].bytecode = new byte[]{ (byte) 0xDB, (byte) (mod_rm_bx_p | mod_op_5)}; // FLD m80f
  473.  
  474.         switch(sel_reg) {
  475.         case 0:
  476.             break;
  477.         case 1:
  478.             instruction[1].bytecode = mov_s0_s1;
  479.             break;
  480.         default: assert false;
  481.         }
  482.        
  483.         return instruction;
  484.     }
  485.  
  486.     public static IntelInstruction[] storeFloat(boolean integer) {
  487.         // input: s0
  488.         // output: mem (bx)
  489.        
  490.         IntelInstruction instruction[] = new IntelInstruction[] {
  491.                 new IntelInstruction(),
  492.                 new IntelInstruction(),
  493.         };
  494.  
  495.         if(integer) {
  496.             instruction[0].bytecode = new byte[]{ (byte) 0xDB, (byte) (mod_rm_bx_p | mod_op_2)}; // FIST m32i
  497.         }
  498.         else {
  499.             instruction[0].bytecode = new byte[]{ (byte) 0xDB, (byte) (mod_rm_bx_p | mod_op_7)}; // FSTP m80f
  500.             instruction[1].bytecode = mov_s0_s1;
  501.         }
  502.        
  503.         return instruction;
  504.     }
  505.    
  506.     public static IntelInstruction[] castIntegerBoolean(int sel_reg) {
  507.         // input: 0:ax 1:bx
  508.         // output: 0 if == 0 otherwise 1
  509.        
  510.         IntelInstruction instruction[] = new IntelInstruction[] {
  511.                 new IntelInstruction(),
  512.                 new IntelInstruction(),
  513.                 new IntelInstruction(),
  514.         };
  515.        
  516.         switch(sel_reg) {// TODO use XOR
  517.         case sel_ax:
  518.             instruction[0].bytecode = new byte[]{ (byte) 0x09, (byte) (mod_rm_ax | mod_reg_ax)}; // OR r/m32, r32
  519.             instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x95, (byte) (mod_rm_ax)}; // SETNZ r/m8
  520.             instruction[2].bytecode = extract_bit1_ax;
  521.             break;
  522.         case sel_cx:
  523.             instruction[0].bytecode = new byte[]{ (byte) 0x09, (byte) (mod_rm_cx | mod_reg_cx)}; // OR r/m32, r32
  524.             instruction[1].bytecode = new byte[]{ (byte) 0x0F, (byte) 0x95, (byte) (mod_rm_cx)}; // SETNZ r/m8
  525.             instruction[2].bytecode = extract_bit1_cx;
  526.             break;
  527.         default: assert false;
  528.         }
  529.        
  530.         return instruction;
  531.     }
  532.    
  533.     public static IntelInstruction[] loadAddress(int physicalAddress) {
  534.         // output: bx
  535.        
  536.         IntelInstruction instruction[] = new IntelInstruction[] {
  537.                 new IntelInstruction(),
  538.         };
  539.        
  540.         byte[] b = new byte[]{
  541.                 (byte) ((physicalAddress & 0x000000FF) >>> 0),
  542.                 (byte) ((physicalAddress & 0x0000FF00) >>> 8),
  543.                 (byte) ((physicalAddress & 0x00FF0000) >>> 16),
  544.                 (byte) ((physicalAddress & 0xFF000000) >>> 24),
  545.         };
  546.         instruction[0].bytecode = new byte[]{ (byte) (0xB8 + add_bx), b[0], b[1], b[2], b[3]}; // MOV r32, i32
  547.        
  548.         return instruction;
  549.     }
  550.    
  551.     public static IntelInstruction[] loadJumpAddress(BytecodeOffset[] offset) {
  552.         // output: bx
  553.        
  554.         IntelInstruction instruction[] = new IntelInstruction[] {
  555.                 new IntelInstruction(),
  556.         };
  557.        
  558.         instruction[0].bytecode = new byte[]{ (byte) (0xB8 + add_bx), 0, 0, 0, 0}; // MOV r32, i32
  559.         assert instruction[0].bytecode.length == 5;
  560.  
  561.         instruction[0].locate = true;
  562.         instruction[0].offset = offset;
  563.        
  564.         return instruction;
  565.     }
  566.    
  567.     public static IntelInstruction[] loadIntegerConstant(int sel_reg, int constant) {
  568.         // output: ax
  569.        
  570.         IntelInstruction instruction[] = new IntelInstruction[] {
  571.                 new IntelInstruction(),
  572.         };
  573.  
  574.         byte[] b = new byte[]{
  575.                 (byte) ((constant & 0x000000FF) >>> 0),
  576.                 (byte) ((constant & 0x0000FF00) >>> 8),
  577.                 (byte) ((constant & 0x00FF0000) >>> 16),
  578.                 (byte) ((constant & 0xFF000000) >>> 24),
  579.         };
  580.         switch(sel_reg) {
  581.         case sel_ax:
  582.             instruction[0].bytecode = new byte[]{ (byte) (0xB8 + add_ax), b[0], b[1], b[2], b[3]}; // MOV r32, i32
  583.             break;
  584.         case sel_cx:
  585.             instruction[0].bytecode = new byte[]{ (byte) (0xB8 + add_cx), b[0], b[1], b[2], b[3]}; // MOV r32, i32
  586.             break;
  587.         default: assert false;
  588.         }
  589.        
  590.         return instruction;
  591.     }
  592.    
  593.     public static IntelInstruction[] storeIntegerConstant(int constant) {
  594.         // output: mem (bx)
  595.        
  596.         IntelInstruction instruction[] = new IntelInstruction[] {
  597.                 new IntelInstruction(),
  598.         };
  599.  
  600.         byte[] b = new byte[]{
  601.                 (byte) ((constant & 0x000000FF) >>> 0),
  602.                 (byte) ((constant & 0x0000FF00) >>> 8),
  603.                 (byte) ((constant & 0x00FF0000) >>> 16),
  604.                 (byte) ((constant & 0xFF000000) >>> 24),
  605.         };
  606.        
  607.         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
  608.        
  609.         return instruction;
  610.     }
  611.    
  612.     /*public static IntelInstruction[] loadInterruptDescriptorTable() {
  613.         IntelInstruction instruction[] = new IntelInstruction[] {
  614.                 new IntelInstruction(),
  615.         };
  616.  
  617.         instruction[0].bytecode = new byte[]{ (byte) 0x00}; // LIDT
  618.        
  619.         return instruction;
  620.     }
  621.    
  622.     public static IntelInstruction[] loadGlobalDescriptorTable() {
  623.         IntelInstruction instruction[] = new IntelInstruction[] {
  624.                 new IntelInstruction(),
  625.         };
  626.  
  627.         instruction[0].bytecode = new byte[]{ (byte) 0x00}; // LIDT
  628.        
  629.         return instruction;
  630.     }
  631.    
  632.     public static IntelInstruction[] loadLocalDescriptorTable() {
  633.         IntelInstruction instruction[] = new IntelInstruction[] {
  634.                 new IntelInstruction(),
  635.         };
  636.  
  637.         instruction[0].bytecode = new byte[]{ (byte) 0x00}; // LIDT
  638.        
  639.         return instruction;
  640.     }
  641.    
  642.     public static IntelInstruction[] loadTaskStateSegment() {
  643.         IntelInstruction instruction[] = new IntelInstruction[] {
  644.                 new IntelInstruction(),
  645.         };
  646.  
  647.         instruction[0].bytecode = new byte[]{ (byte) 0x00}; // LIDT
  648.        
  649.         return instruction;
  650.     }*/
  651. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement