#include "../BasicCompiler_Common/common.h" #include "Opcode.h" BOOL IsSafeReg(int reg){ switch(reg){ case REG_RBX: case REG_RSI: case REG_RDI: case REG_R12: case REG_R13: case REG_R14: case REG_R15: return 1; default: break; } return 0; } ////////////////////// // rexプリフィックス ////////////////////// void set_rex(int op_size,int reg,int index_reg,int base_reg){ char RexByte; if(reg==REG_NON&&index_reg==REG_NON){ ///////////////////////////////////// // レジスタをr/mのみに指定するとき ///////////////////////////////////// if((base_reg&0x08)==0){ if(op_size==sizeof(char)&&(base_reg&0x04)){ // r/m に spl,bpl,sil,dilを指定するとき RexByte=0x40; } else RexByte=0; } else RexByte=(char)0x41; } else{ ///////////////// // 通常 ///////////////// if((reg&0x08)==0){ //reg … rax〜rdi if((index_reg&0x08)==0){ if((base_reg&0x08)==0) RexByte=0; else RexByte=(char)0x41; } else{ if((base_reg&0x08)==0) RexByte=(char)0x42; else RexByte=(char)0x43; } } else{ //reg … r8〜r15 if((index_reg&0x08)==0){ if((base_reg&0x08)==0) RexByte=(char)0x44; else RexByte=(char)0x45; } else{ if((base_reg&0x08)==0) RexByte=(char)0x46; else RexByte=(char)0x47; } } } if(op_size==sizeof(_int64)){ //64ビットオペランド RexByte|=0x48; } if(RexByte) OpBuffer[obp++]=RexByte; } ///////////////////////////////////////////////// // ModR/Mバイト、SIBバイト、ディスプレースメント ///////////////////////////////////////////////// //スケール #define SCALE_NON (char)0x00 #define SCALE_2 (char)0x40 #define SCALE_4 (char)0x80 #define SCALE_8 (char)0xC0 //インデックスなし #define INDEX_NON 0x04 void set_mod_rm_sib_disp(char mod,int reg,int scale,int index_reg,int base_reg,int disp){ if(mod==MOD_DISP32){ //ModR/Mバイト OpBuffer[obp++]=(char)( REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(0x04)); base_reg=0x05; index_reg=INDEX_NON; } else{ //ModR/Mバイト OpBuffer[obp++]=(char)(mod | REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(base_reg)); } //レジスタモードの場合は、ここで終了 if(mod==MOD_REG) return; if(REGISTER_OPERAND(base_reg)==0x04||mod==MOD_DISP32){ ////////////////////// // SIBバイトを使う ////////////////////// OpBuffer[obp++]=(char)(scale| REGISTER_OPERAND(index_reg)<<3 | REGISTER_OPERAND(base_reg)); } //ディスプレースメントを必要としない場合は、ここで終了 if(mod==MOD_BASE) return; ////////////////////////// // ディスプレースメント ////////////////////////// if(mod==MOD_BASE_DISP8) OpBuffer[obp++]=(char)disp; else{ *((long *)(OpBuffer+obp))=disp; obp+=sizeof(long); } } void __op_format(int op_size,char op_prefix,char opcode1,char opcode2,int reg,int base_reg,int offset,char mod){ //命令プリフィックス if(op_prefix) OpBuffer[obp++]=op_prefix; //rexプリフィックス set_rex(op_size,reg,0,base_reg); //オペコード OpBuffer[obp++]=opcode1; if(opcode2) OpBuffer[obp++]=opcode2; //ModR/M, SIB, disp set_mod_rm_sib_disp(mod,reg,SCALE_NON,INDEX_NON,base_reg,offset); } ////////////////////////// // スタック関連 ////////////////////////// void op_push(int reg){ //スタックにレジスタの値をプッシュ if(REG_RAX<=reg&®<=REG_RDI){ /* rax〜rdi 0101 0xxx */ OpBuffer[obp++]=(char)(0x50| REGISTER_OPERAND(reg) ); } if(REG_R8<=reg&®<=REG_R15){ /* r8〜r15 0100 0001 0101 0xxx */ OpBuffer[obp++]=(char)0x41; OpBuffer[obp++]=(char)(0x50| REGISTER_OPERAND(reg) ); } } void op_push_value(long data){ //スタックにリテラル値をプッシュ if(-128<=data&&data<=127){ //push 8ビット値 OpBuffer[obp++]=(char)0x6A; OpBuffer[obp++]=(char)data; } else{ //push 32ビット値 OpBuffer[obp++]=(char)0x68; *((long *)(OpBuffer+obp))=data; obp+=sizeof(long); } } void op_pop(int reg){ //スタックの内容をレジスタにポップ if(REG_RAX<=reg&®<=REG_RDI){ /* rax〜rdi 0101 1xxx */ OpBuffer[obp++]=(char)(0x58| REGISTER_OPERAND(reg) ); } if(REG_R8<=reg&®<=REG_R15){ /* r8〜r15 0100 0001 0101 1xxx */ OpBuffer[obp++]=(char)0x41; OpBuffer[obp++]=(char)(0x58| REGISTER_OPERAND(reg) ); } } /////////////////// // mov関連 /////////////////// void op_mov_RV(int op_size,int reg,int i32data){ //mov reg,i32data //rexプリフィックス set_rex(op_size,REG_NON,REG_NON,reg); if(op_size==sizeof(_int64)){ //オペコード OpBuffer[obp++]=(char)0xC7; //レジスタ OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg) ); } else{ //レジスタ OpBuffer[obp++]=(char)(0xB8| REGISTER_OPERAND(reg) ); } //即値 *((long *)(OpBuffer+obp))=i32data; obp+=sizeof(long); } void op_mov_RV64(int reg,_int64 i64data){ //mov reg,i64data //rexプリフィックス set_rex(sizeof(_int64),REG_NON,REG_NON,reg); //レジスタ OpBuffer[obp++]=(char)(0xB8| REGISTER_OPERAND(reg) ); //即値 *((_int64 *)(OpBuffer+obp))=i64data; obp+=sizeof(_int64); } void op_mov_RM(int op_size,int reg,int base_reg,int offset,char mod){ //mov reg64,qword ptr[base_reg+offset] //mov reg32,dword ptr[base_reg+offset] //mov reg16,word ptr[base_reg+offset] //mov reg8,byte ptr[base_reg+offset] //16ビット演算の命令プリフィックス char op_prefix=0; if(op_size==sizeof(short)) op_prefix=(char)0x66; //オペコード char opcode; if(op_size==sizeof(char)) opcode=(char)0x8A; else opcode=(char)0x8B; __op_format(op_size,op_prefix,opcode,0,reg,base_reg,offset,mod); } void op_mov_RM_ex(int op_size,int reg,int base_reg1,int base_reg2,int offset,BOOL bUseOffset){ //mov reg64,qword ptr[base_reg1+base_reg2+offset] //mov reg32,dword ptr[base_reg1+base_reg2+offset] //mov reg16,word ptr[base_reg1+base_reg2+offset] //mov reg8,byte ptr[base_reg1+base_reg2+offset] if(base_reg1==REG_RSP){ //SIBバイトのindex部にrspは指定できない base_reg1=base_reg2; base_reg2=REG_RSP; } //16ビット演算のプリフィックス if(op_size==sizeof(short)) OpBuffer[obp++]=(char)0x66; //rexプリフィックス set_rex(op_size,reg,base_reg1,base_reg2); //オペコード if(op_size==sizeof(char)) OpBuffer[obp++]=(char)0x8A; else OpBuffer[obp++]=(char)0x8B; if(bUseOffset){ /////////////////////////// // オフセット値を使う /////////////////////////// //レジスタ OpBuffer[obp++]=(char)(0x84| REGISTER_OPERAND(reg)<<3); //ベースレジスタ OpBuffer[obp++]=(char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2)); //オフセット値 *((long *)(OpBuffer+obp))=offset; obp+=sizeof(long); } else{ /////////////////////////// // オフセット値を使わない /////////////////////////// //レジスタ OpBuffer[obp++]=(char)(0x04| REGISTER_OPERAND(reg)<<3); //ベースレジスタ OpBuffer[obp++]=(char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2)); } } void op_mov_MR(int op_size,int reg,int base_reg,int offset,char mod){ //mov qword ptr[base_reg+offset],reg64 //mov dword ptr[base_reg+offset],reg32 //mov word ptr[base_reg+offset],reg16 //mov byte ptr[base_reg+offset],reg8 //16ビット演算の命令プリフィックス char op_prefix=0; if(op_size==sizeof(short)) op_prefix=(char)0x66; //オペコード char opcode; if(op_size==sizeof(char)) opcode=(char)0x88; else opcode=(char)0x89; __op_format(op_size,op_prefix,opcode,0,reg,base_reg,offset,mod); } void op_mov_MR_ex(int op_size,int reg,int base_reg1,int base_reg2,int offset,BOOL bUseOffset){ //mov qword ptr[base_reg1+base_reg2+offset],reg64 //mov dword ptr[base_reg1+base_reg2+offset],reg32 //mov word ptr[base_reg1+base_reg2+offset],reg16 //mov byte ptr[base_reg1+base_reg2+offset],reg8 if(base_reg1==REG_RSP){ //SIBバイトのindex部にrspは指定できない base_reg1=base_reg2; base_reg2=REG_RSP; } //16ビット演算のプリフィックス if(op_size==sizeof(short)) OpBuffer[obp++]=(char)0x66; //rexプリフィックス set_rex(op_size,reg,base_reg1,base_reg2); //オペコード if(op_size==sizeof(char)) OpBuffer[obp++]=(char)0x88; else OpBuffer[obp++]=(char)0x89; if(bUseOffset==USE_OFFSET){ ////////////////////////// //オフセット値を使う ////////////////////////// //レジスタ OpBuffer[obp++]=(char)(0x84| REGISTER_OPERAND(reg)<<3); //ベースレジスタ OpBuffer[obp++]=(char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2)); //オフセット値 *((long *)(OpBuffer+obp))=offset; obp+=sizeof(long); } else{ ////////////////////////// //オフセット値を使わない ////////////////////////// //レジスタ OpBuffer[obp++]=(char)(0x04| REGISTER_OPERAND(reg)<<3); //ベースレジスタ OpBuffer[obp++]=(char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2)); } } void op_mov_MV(int op_size,int base_reg,int offset,BOOL bUseOffset,int i32data){ //mov ptr[base_reg+offset],i32data //mov ptr[base_reg ],i32data //16ビット演算のプリフィックス if(op_size==sizeof(short)) OpBuffer[obp++]=(char)0x66; //rexプリフィックス set_rex(op_size,0,0,base_reg); //オペコード if(op_size==sizeof(char)) OpBuffer[obp++]=(char)0xC6; else OpBuffer[obp++]=(char)0xC7; if(bUseOffset==USE_OFFSET){ ////////////////////////// //オフセット値を使う ////////////////////////// //ModR/M, SIB, disp set_mod_rm_sib_disp(MOD_BASE_DISP32,0,SCALE_NON,INDEX_NON,base_reg,offset); } else{ //ModR/M, SIB, disp set_mod_rm_sib_disp(MOD_BASE,0,SCALE_NON,INDEX_NON,base_reg,0); } //即値 if(op_size==sizeof(_int64)||op_size==sizeof(long)){ //32/64ビット *((long *)(OpBuffer+obp))=i32data; obp+=sizeof(long); } else if(op_size==sizeof(short)){ //16ビット *((short *)(OpBuffer+obp))=(short)i32data; obp+=sizeof(short); } else if(op_size==sizeof(char)){ //16ビット *((char *)(OpBuffer+obp))=(char)i32data; obp++; } } void op_mov_RR(int reg1,int reg2){ op_mov64_ToReg_FromReg(reg1,reg2); } /////////////////// // mov64関連 /////////////////// void op_mov64_ToReg(int reg,_int64 i64data){ //mov reg,i64data if(REG_RAX<=reg&®<=REG_RDI){ /* rax〜rdi 0100 1000 1011 1xxx [64bit data] */ OpBuffer[obp++]=(char)0x48; OpBuffer[obp++]=(char)(0xB8| REGISTER_OPERAND(reg) ); *((_int64 *)(OpBuffer+obp))=i64data; obp+=sizeof(_int64); } if(REG_R8<=reg&®<=REG_R15){ /* r8〜r15 0100 1001 1011 1xxx [64bit data] */ OpBuffer[obp++]=(char)0x49; OpBuffer[obp++]=(char)(0xB8| REGISTER_OPERAND(reg) ); *((_int64 *)(OpBuffer+obp))=i64data; obp+=sizeof(_int64); } } void op_mov64_ToReg(int reg,int i32data){ //mov reg,i32data if(REG_RAX<=reg&®<=REG_RDI){ /* rax〜rdi 0100 1000 1100 0111 1100 0xxx [32bit data] */ OpBuffer[obp++]=(char)0x48; OpBuffer[obp++]=(char)0xC7; OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg) ); *((long *)(OpBuffer+obp))=i32data; obp+=sizeof(long); } if(REG_R8<=reg&®<=REG_R15){ /* r8〜r15 0100 1001 1100 0111 1100 0xxx [32bit data] */ OpBuffer[obp++]=(char)0x49; OpBuffer[obp++]=(char)0xC7; OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg) ); *((long *)(OpBuffer+obp))=i32data; obp+=sizeof(long); } } void op_mov64_ToReg_FromReg(int reg1,int reg2){ //mov reg1,reg2 char RexByte=-1; if(reg1==reg2) return; if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x4D; } if(RexByte==-1) SetError(300,NULL,cp); // [8bit rex] 1000 1011 11xx xbbb OpBuffer[obp++]=RexByte; OpBuffer[obp++]=(char)0x8B; OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)); } void op_movsxd(int reg64,int reg32){ //movsxd reg64,reg32 char RexByte=-1; if(REG_RAX<=reg64&®64<=REG_RDI){ if(REG_RAX<=reg32&®32<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg32&®32<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg64&®64<=REG_R15){ if(REG_RAX<=reg32&®32<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg32&®32<=REG_R15) RexByte=(char)0x4D; } if(RexByte==-1) SetError(300,NULL,cp); //[8bit rex] 0110 0011 11rr rbbb OpBuffer[obp++]=RexByte; OpBuffer[obp++]=(char)0x63; OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg64)<<3 | REGISTER_OPERAND(reg32)); } void op_movsx64_FromReg16(int reg64,int reg16){ //movsx reg64,reg16 char RexByte=-1; if(REG_RAX<=reg64&®64<=REG_RDI){ if(REG_RAX<=reg16&®16<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg16&®16<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg64&®64<=REG_R15){ if(REG_RAX<=reg16&®16<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg16&®16<=REG_R15) RexByte=(char)0x4D; } if(RexByte==-1) SetError(300,NULL,cp); //[8bit rex] 0000 1111 1011 1111 11rr rbbb OpBuffer[obp++]=RexByte; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0xBF; OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg64)<<3 | REGISTER_OPERAND(reg16)); } void op_movsx64_FromReg8(int reg64,int reg8){ //movsx reg64,reg8 char RexByte=-1; if(REG_RAX<=reg64&®64<=REG_RDI){ if(REG_RAX<=reg8&®8<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg8&®8<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg64&®64<=REG_R15){ if(REG_RAX<=reg8&®8<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg8&®8<=REG_R15) RexByte=(char)0x4D; } if(RexByte==-1) SetError(300,NULL,cp); //[8bit rex] 0000 1111 1011 1110 11rr rbbb OpBuffer[obp++]=RexByte; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0xBE; OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg64)<<3 | REGISTER_OPERAND(reg8)); } ////////////////// // mov32関連 ////////////////// void op_movsx32_FromReg16(int reg32,int reg16){ //movsx reg32,reg16 char RexByte=-1; if(REG_RAX<=reg32&®32<=REG_RDI){ if(REG_RAX<=reg16&®16<=REG_RDI) RexByte=0; if(REG_R8<=reg16&®16<=REG_R15) RexByte=(char)0x41; } if(REG_R8<=reg32&®32<=REG_R15){ if(REG_RAX<=reg16&®16<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg16&®16<=REG_R15) RexByte=(char)0x45; } if(RexByte==-1) SetError(300,NULL,cp); //[8bit rex] 0000 1111 1011 1111 11rr rbbb if(RexByte) OpBuffer[obp++]=RexByte; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0xBF; OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg32)<<3 | REGISTER_OPERAND(reg16)); } void op_movsx32_FromReg8(int reg32,int reg8){ //movsx reg32,reg8 char RexByte=-1; if(REG_RAX<=reg32&®32<=REG_RDI){ if(REG_RAX<=reg8&®8<=REG_RBX) RexByte=0; if(REG_RSP<=reg8&®8<=REG_RDI) RexByte=(char)0x40; if(REG_R8<=reg8&®8<=REG_R15) RexByte=(char)0x41; } if(REG_R8<=reg32&®32<=REG_R15){ if(REG_RAX<=reg8&®8<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg8&®8<=REG_R15) RexByte=(char)0x45; } if(RexByte==-1) SetError(300,NULL,cp); //[8bit rex] 0000 1111 1011 1110 11rr rbbb if(RexByte) OpBuffer[obp++]=RexByte; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0xBE; OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg32)<<3 | REGISTER_OPERAND(reg8)); } ///////////////////// // mov16関連 ///////////////////// void op_movsx16_FromReg8(int reg32,int reg8){ //movsx reg16,reg8 char RexByte=-1; if(REG_RAX<=reg32&®32<=REG_RDI){ if(REG_RAX<=reg8&®8<=REG_RBX) RexByte=0; if(REG_RSP<=reg8&®8<=REG_RDI) RexByte=(char)0x40; if(REG_R8<=reg8&®8<=REG_R15) RexByte=(char)0x41; } if(REG_R8<=reg32&®32<=REG_R15){ if(REG_RAX<=reg8&®8<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg8&®8<=REG_R15) RexByte=(char)0x45; } if(RexByte==-1) SetError(300,NULL,cp); //0110 0110 [8bit rex] 0000 1111 1011 1110 11rr rbbb OpBuffer[obp++]=(char)0x66; if(RexByte) OpBuffer[obp++]=RexByte; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0xBE; OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg32)<<3 | REGISTER_OPERAND(reg8)); } ////////////////////////////////// // インクリメント・デクリメント ////////////////////////////////// void op_inc(int reg){ //inc reg //16ビット演算の命令プリフィックス char op_prefix=0; //オペコード char opcode=(char)0xFF; __op_format(sizeof(_int64),op_prefix,opcode,0,0,reg,0,MOD_REG); } void op_dec(int reg){ op_inc(reg); OpBuffer[obp-1]=OpBuffer[obp-1]|0x08; } ///////////////////// // add関連 ///////////////////// void op_add_RM(int op_size,int reg,int base_reg,int offset,char mod){ //add reg64,qword ptr[base_reg+offset] //add reg32,dword ptr[base_reg+offset] //add reg16,word ptr[base_reg+offset] //add reg8,byte ptr[base_reg+offset] //16ビット演算の命令プリフィックス char op_prefix=0; if(op_size==sizeof(short)) op_prefix=(char)0x66; //オペコード char opcode; if(op_size==sizeof(char)) opcode=(char)0x02; else opcode=(char)0x03; __op_format(op_size,op_prefix,opcode,0,reg,base_reg,offset,mod); } void op_add64_value(int reg,int offset){ //add reg,offset char RexByte=-1; if(REG_RAX<=reg&®<=REG_RDI) RexByte=0x48; if(REG_R8<=reg&®<=REG_R15) RexByte=0x49; if(RexByte==-1) SetError(300,NULL,cp); if(reg==REG_RAX){ //raxのみ特殊 // [8bit rex] 0000 0101 [32bit offset] OpBuffer[obp++]=(char)RexByte; OpBuffer[obp++]=(char)0x05; *((long *)(OpBuffer+obp))=offset; obp+=sizeof(long); } else{ //rax以外 //[8bit rex] 1000 0001 1100 0xxx [32bit offset] OpBuffer[obp++]=(char)RexByte; OpBuffer[obp++]=(char)0x81; OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg)); *((long *)(OpBuffer+obp))=offset; obp+=sizeof(long); } } void op_add64_reg(int reg1,int reg2){ //add reg1,reg2 char RexByte=-1; if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x4D; } if(RexByte==-1) SetError(300,NULL,cp); //[8bit rex] 0000 0011 11rr rbbb OpBuffer[obp++]=(char)RexByte; OpBuffer[obp++]=(char)0x03; OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)); } void op_add32_reg(int reg1,int reg2){ //add reg1,reg2 char RexByte=-1; if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=0; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x41; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x45; } if(RexByte==-1) SetError(300,NULL,cp); //[8bit rex] 0000 0011 11rr rbbb if(RexByte) OpBuffer[obp++]=(char)RexByte; OpBuffer[obp++]=(char)0x03; OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)); } //////////////////////// // sub関連 //////////////////////// void op_sub_RV(int op_size,int reg,int i32data){ //sub reg,i32data //rexプリフィックス set_rex(op_size,REG_NON,REG_NON,reg); if(reg==REG_RAX){ //raxのみ特殊 OpBuffer[obp++]=(char)0x2D; } else{ //オペコード OpBuffer[obp++]=(char)0x81; //レジスタ OpBuffer[obp++]=(char)(0xE8| REGISTER_OPERAND(reg) ); } //即値 *((long *)(OpBuffer+obp))=i32data; obp+=sizeof(long); } void op_sub64_reg(int reg1,int reg2){ //sub reg1,reg2 char RexByte=-1; if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x4D; } if(RexByte==-1) SetError(300,NULL,cp); //[8bit rex] 0010 1011 11rr rbbb OpBuffer[obp++]=(char)RexByte; OpBuffer[obp++]=(char)0x2B; OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)); } void op_sub32_reg(int reg1,int reg2){ //sub reg1,reg2 char RexByte=-1; if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=0; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x41; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x45; } if(RexByte==-1) SetError(300,NULL,cp); //[8bit rex] 0010 1011 11rr rbbb if(RexByte) OpBuffer[obp++]=(char)RexByte; OpBuffer[obp++]=(char)0x2B; OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)); } //////////////////////// // imul関連 //////////////////////// void op_imul_reg(int op_size,int reg1,int reg2){ //imul reg1,reg2 char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x4D; } } else{ if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=0; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x41; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x45; } } if(RexByte==-1) SetError(300,NULL,cp); //rexプリフィックス if(RexByte) OpBuffer[obp++]=(char)RexByte; //オペコード OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0xAF; //レジスタ OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)); } void op_imul_value(int op_size,int reg,int i32data){ //imul reg,i32data char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x4D; } else{ if(REG_RAX<=reg&®<=REG_RDI) RexByte=0; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x45; } if(RexByte==-1) SetError(300,NULL,cp); //rexプリフィックス if(RexByte) OpBuffer[obp++]=(char)RexByte; if(-128<=i32data&&i32data<=127){ //オペコード OpBuffer[obp++]=(char)0x6B; //レジスタ OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(reg)); //値 OpBuffer[obp++]=(char)i32data; } else{ //オペコード OpBuffer[obp++]=(char)0x69; //レジスタ OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(reg)); //値 *((long *)(OpBuffer+obp))=i32data; obp+=sizeof(long); } } //////////////////////// // div、idiv関連 //////////////////////// void op_div64_reg(int reg){ //div reg char RexByte=-1; if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x49; if(RexByte==-1) SetError(300,NULL,cp); //rexプリフィックス OpBuffer[obp++]=(char)RexByte; //オペコード OpBuffer[obp++]=(char)0xF7; //レジスタ OpBuffer[obp++]=(char)(0xF0| REGISTER_OPERAND(reg)); } void op_idiv64_reg(int reg){ //idiv reg char RexByte=-1; if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x49; if(RexByte==-1) SetError(300,NULL,cp); //rexプリフィックス OpBuffer[obp++]=(char)RexByte; //オペコード OpBuffer[obp++]=(char)0xF7; //レジスタ OpBuffer[obp++]=(char)(0xF8| REGISTER_OPERAND(reg)); } //////////////////// // ビットシフト関連 //////////////////// void op_shl_reg(int op_size,int reg){ //shl reg,cl char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x49; } else if(op_size==sizeof(char)){ if(REG_RAX<=reg&®<=REG_RBX) RexByte=0; if(REG_RSP<=reg&®<=REG_RDI) RexByte=(char)0x40; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x41; } else{ if(REG_RAX<=reg&®<=REG_RDI) RexByte=0; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x41; } if(RexByte==-1) SetError(300,NULL,cp); //16ビット演算のプリフィックス if(op_size==sizeof(short)) OpBuffer[obp++]=(char)0x66; //rexプリフィックス if(RexByte) OpBuffer[obp++]=(char)RexByte; //オペコード if(op_size==sizeof(char)) OpBuffer[obp++]=(char)0xD2; else OpBuffer[obp++]=(char)0xD3; //レジスタ OpBuffer[obp++]=(char)(0xE0| REGISTER_OPERAND(reg)); } void op_sar_reg(int op_size,int reg){ //sar reg,cl char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x49; } else if(op_size==sizeof(char)){ if(REG_RAX<=reg&®<=REG_RBX) RexByte=0; if(REG_RSP<=reg&®<=REG_RDI) RexByte=(char)0x40; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x41; } else{ if(REG_RAX<=reg&®<=REG_RDI) RexByte=0; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x41; } if(RexByte==-1) SetError(300,NULL,cp); //16ビット演算のプリフィックス if(op_size==sizeof(short)) OpBuffer[obp++]=(char)0x66; //rexプリフィックス if(RexByte) OpBuffer[obp++]=(char)RexByte; //オペコード if(op_size==sizeof(char)) OpBuffer[obp++]=(char)0xD2; else OpBuffer[obp++]=(char)0xD3; //レジスタ OpBuffer[obp++]=(char)(0xF8| REGISTER_OPERAND(reg)); } void op_shr_reg(int op_size,int reg){ //shr reg,cl char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x49; } else if(op_size==sizeof(char)){ if(REG_RAX<=reg&®<=REG_RBX) RexByte=0; if(REG_RSP<=reg&®<=REG_RDI) RexByte=(char)0x40; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x41; } else{ if(REG_RAX<=reg&®<=REG_RDI) RexByte=0; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x41; } if(RexByte==-1) SetError(300,NULL,cp); //16ビット演算のプリフィックス if(op_size==sizeof(short)) OpBuffer[obp++]=(char)0x66; //rexプリフィックス if(RexByte) OpBuffer[obp++]=(char)RexByte; //オペコード if(op_size==sizeof(char)) OpBuffer[obp++]=(char)0xD2; else OpBuffer[obp++]=(char)0xD3; //レジスタ OpBuffer[obp++]=(char)(0xE8| REGISTER_OPERAND(reg)); } //////////////////// // and 関連 //////////////////// void op_and_reg(int op_size,int reg1,int reg2){ //and reg1,reg2 char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x4D; } } else{ if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=0; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x41; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x45; } } if(RexByte==-1) SetError(300,NULL,cp); //rexプリフィックス if(RexByte) OpBuffer[obp++]=(char)RexByte; //オペコード OpBuffer[obp++]=(char)0x23; //レジスタ OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)); } void op_and64_value(int reg,int offset){ //and reg,offset char RexByte=-1; if(REG_RAX<=reg&®<=REG_RDI) (char)RexByte=0x48; if(REG_R8<=reg&®<=REG_R15) (char)RexByte=0x49; if(RexByte==-1) SetError(300,NULL,cp); if(reg==REG_RAX){ //raxのみ特殊 // [8bit rex] 0010 0101 [32bit offset] OpBuffer[obp++]=(char)RexByte; OpBuffer[obp++]=(char)0x25; *((long *)(OpBuffer+obp))=offset; obp+=sizeof(long); } else{ //rax以外 //[8bit rex] 1000 0001 1100 0xxx [32bit offset] OpBuffer[obp++]=(char)RexByte; OpBuffer[obp++]=(char)0x81; OpBuffer[obp++]=(char)(0xE0| REGISTER_OPERAND(reg)); *((long *)(OpBuffer+obp))=offset; obp+=sizeof(long); } } void op_and32_value(int reg,int offset){ //and reg,offset char RexByte=-1; if(REG_RAX<=reg&®<=REG_RDI) RexByte=0; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x41; if(RexByte==-1) SetError(300,NULL,cp); if(reg==REG_RAX){ //eaxのみ特殊 // [8bit rex] 0010 0101 [32bit offset] OpBuffer[obp++]=(char)0x25; *((long *)(OpBuffer+obp))=offset; obp+=sizeof(long); } else{ //eax以外 //[8bit rex] 1000 0001 1100 0xxx [32bit offset] if(RexByte) OpBuffer[obp++]=(char)RexByte; OpBuffer[obp++]=(char)0x81; OpBuffer[obp++]=(char)(0xE0| REGISTER_OPERAND(reg)); *((long *)(OpBuffer+obp))=offset; obp+=sizeof(long); } } //////////////////////// // or 関連 //////////////////////// void op_or_reg(int op_size,int reg1,int reg2){ //or reg1,reg2 char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x4D; } } else{ if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=0; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x41; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x45; } } if(RexByte==-1) SetError(300,NULL,cp); //rexプリフィックス if(RexByte) OpBuffer[obp++]=(char)RexByte; //オペコード OpBuffer[obp++]=(char)0x0B; //レジスタ OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)); } //////////////////////// // xor 関連 //////////////////////// void op_xor_reg(int op_size,int reg1,int reg2){ //xor reg1,reg2 char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x4D; } } else{ if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=0; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x41; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x45; } } if(RexByte==-1) SetError(300,NULL,cp); //rexプリフィックス if(RexByte) OpBuffer[obp++]=(char)RexByte; //オペコード OpBuffer[obp++]=(char)0x33; //レジスタ OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)); } /////////////////////// // not 関連 /////////////////////// void op_not_reg(int op_size,int reg){ //not reg char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x49; } else{ if(REG_RAX<=reg&®<=REG_RDI) RexByte=0; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x41; } if(RexByte==-1) SetError(300,NULL,cp); //rexプリフィックス if(RexByte) OpBuffer[obp++]=(char)RexByte; //オペコード OpBuffer[obp++]=(char)0xF7; //レジスタ OpBuffer[obp++]=(char)(0xD0| REGISTER_OPERAND(reg)); } //////////////////// // test関連 //////////////////// void op_test(int reg1,int reg2){ //test reg1,reg2 char RexByte=-1; if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x4D; } if(RexByte==-1) SetError(300,NULL,cp); //[8bit rex] 1000 0101 11rr rbbb OpBuffer[obp++]=(char)RexByte; OpBuffer[obp++]=(char)0x85; OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)); } ///////////////////// // cmp 関連 ///////////////////// void op_cmp_reg(int op_size,int reg1,int reg2){ //cmp reg1,reg2 char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x4D; } } else{ if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=0; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x41; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x45; } } if(RexByte==-1) SetError(300,NULL,cp); //rexプリフィックス if(RexByte) OpBuffer[obp++]=(char)RexByte; //オペコード OpBuffer[obp++]=(char)0x3B; //レジスタ OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)); } void op_cmp_value(int op_size,int reg,char byte_data){ //cmp reg,byte_data if(op_size==sizeof(char)&®==REG_RAX){ //alレジスタの場合は特殊 OpBuffer[obp++]=(char)0x3C; //8ビット値 OpBuffer[obp++]=byte_data; return; } //16ビット演算のプリフィックス if(op_size==sizeof(short)) OpBuffer[obp++]=(char)0x66; //rexプリフィックス set_rex(op_size,REG_NON,REG_NON,reg); //オペコード if(op_size==sizeof(char)) OpBuffer[obp++]=(char)0x80; else OpBuffer[obp++]=(char)0x83; //レジスタ OpBuffer[obp++]=(char)(0xF8| REGISTER_OPERAND(reg)); //8ビット値 OpBuffer[obp++]=byte_data; } //////////////////// // SSE2関連 //////////////////// void op_movlpd_MR(int xmm_reg,int base_reg,int offset,char mod){ //movlpd qword ptr[base_reg+offset],xmm_reg __op_format(0,(char)0x66,(char)0x0F,(char)0x13,xmm_reg,base_reg,offset,mod); } void op_movlpd_RM(int xmm_reg,int base_reg,int offset,char mod){ //movlpd xmm_reg,qword ptr[base_reg+offset] __op_format(0,(char)0x66,(char)0x0F,(char)0x12,xmm_reg,base_reg,offset,mod); } void op_movsd_RR(int xmm_reg1,int xmm_reg2){ if(xmm_reg1==xmm_reg2) return; //movsd xmm_reg1,xmm_reg2 __op_format(0,(char)0xF2,(char)0x0F,(char)0x10,xmm_reg1,xmm_reg2,0,MOD_REG); } void op_movsd_MR(int xmm_reg,int base_reg,int offset,char mod){ //movsd qword ptr[reg+offset],xmm_reg //movsd qword ptr[reg],xmm_reg __op_format(0,(char)0xF2,(char)0x0F,(char)0x11,xmm_reg,base_reg,offset,mod); } void op_movss_RR(int xmm_reg1,int xmm_reg2){ if(xmm_reg1==xmm_reg2) return; //movss xmm_reg1,xmm_reg2 __op_format(0,(char)0xF3,(char)0x0F,(char)0x10,xmm_reg1,xmm_reg2,0,MOD_REG); } void op_movss_RM(int xmm_reg,int base_reg,int offset,char mod){ //movss xmm_reg,dword ptr[base_reg+offset] __op_format(0,(char)0xF3,(char)0x0F,(char)0x10,xmm_reg,base_reg,offset,mod); } void op_movss_MR(int xmm_reg,int base_reg,int offset,char mod){ //movss dword ptr[reg+offset],xmm_reg //movss dword ptr[reg],xmm_reg __op_format(0,(char)0xF3,(char)0x0F,(char)0x11,xmm_reg,base_reg,offset,mod); } void op_movd_RX(int reg,int xmm_reg){ __op_format(sizeof(_int64),(char)0x66,(char)0x0F,(char)0x7E,xmm_reg,reg,0,MOD_REG); } void op_cvtsd2ss(int xmm_reg1,int xmm_reg2){ //cvtsd2ss xmm_reg1,xmm_reg2 //オペコード OpBuffer[obp++]=(char)0xF2; //rexプリフィックス set_rex(sizeof(long),xmm_reg1,0,xmm_reg2); //オペコード OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x5A; //レジスタ OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(xmm_reg1)<<3 | REGISTER_OPERAND(xmm_reg2)); } void op_cvtss2sd(int xmm_reg1,int xmm_reg2){ //cvtss2sd xmm_reg1,xmm_reg2 //オペコード OpBuffer[obp++]=(char)0xF3; //rexプリフィックス set_rex(0,xmm_reg1,0,xmm_reg2); //オペコード OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x5A; //レジスタ OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(xmm_reg1)<<3 | REGISTER_OPERAND(xmm_reg2)); } void op_cvttsd2si_xmm(int op_size,int reg,int xmm_reg){ //cvttsd2si reg,xmm_reg //オペコード OpBuffer[obp++]=(char)0xF2; //rexプリフィックス set_rex(op_size,reg,0,xmm_reg); //オペコード OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x2C; //レジスタ OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(xmm_reg)); } void op_cvttss2si_xmm(int op_size,int reg,int xmm_reg){ //cvttss2si reg,xmm_reg //オペコード OpBuffer[obp++]=(char)0xF3; //rexプリフィックス set_rex(op_size,reg,0,xmm_reg); //オペコード OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x2C; //レジスタ OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(xmm_reg)); } void op_cvtsi2sd_reg(int op_size,int xmm_reg,int reg){ //cvtsi2sd xmm_reg,reg char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_XMM0<=xmm_reg&&xmm_reg<=REG_XMM7){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x49; } if(REG_XMM8<=xmm_reg&&xmm_reg<=REG_XMM15){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x4D; } } else{ if(REG_XMM0<=xmm_reg&&xmm_reg<=REG_XMM7){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=0; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x41; } if(REG_XMM8<=xmm_reg&&xmm_reg<=REG_XMM15){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x45; } } if(RexByte==-1) SetError(300,NULL,cp); //オペコード OpBuffer[obp++]=(char)0xF2; //rexプリフィックス if(RexByte) OpBuffer[obp++]=(char)RexByte; //オペコード OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x2A; //レジスタ OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(xmm_reg)<<3 | REGISTER_OPERAND(reg)); } void op_cvtsi2ss_reg(int op_size,int xmm_reg,int reg){ //cvtsi2ss xmm_reg,reg char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_XMM0<=xmm_reg&&xmm_reg<=REG_XMM7){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x49; } if(REG_XMM8<=xmm_reg&&xmm_reg<=REG_XMM15){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x4D; } } else{ if(REG_XMM0<=xmm_reg&&xmm_reg<=REG_XMM7){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=0; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x41; } if(REG_XMM8<=xmm_reg&&xmm_reg<=REG_XMM15){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x45; } } if(RexByte==-1) SetError(300,NULL,cp); //オペコード OpBuffer[obp++]=(char)0xF3; //rexプリフィックス if(RexByte) OpBuffer[obp++]=(char)RexByte; //オペコード OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x2A; //レジスタ OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(xmm_reg)<<3 | REGISTER_OPERAND(reg)); } void op_comisd(int xmm_reg1,int xmm_reg2){ //comisd xmm_reg1,xmm_reg2 //オペコード OpBuffer[obp++]=(char)0x66; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x2F; //レジスタ OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(xmm_reg1)<<3 | REGISTER_OPERAND(xmm_reg2)); } void op_comiss(int xmm_reg1,int xmm_reg2){ //comiss xmm_reg1,xmm_reg2 //オペコード OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x2F; //レジスタ OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(xmm_reg1)<<3 | REGISTER_OPERAND(xmm_reg2)); } ///////////////////// // ストリング関係 ///////////////////// void op_rep_movs(int op_size){ if(op_size==sizeof(BYTE)){ //rep movs byte ptr[edi],byte ptr[esi] OpBuffer[obp++]=(char)0xF3; OpBuffer[obp++]=(char)0xA4; } else if(op_size==sizeof(short)){ //rep movs word ptr[edi],word ptr[esi] OpBuffer[obp++]=(char)0xF3; OpBuffer[obp++]=(char)0x66; OpBuffer[obp++]=(char)0xA5; } else if(op_size==sizeof(long)){ //rep movs dword ptr[edi],dword ptr[esi] OpBuffer[obp++]=(char)0xF3; OpBuffer[obp++]=(char)0xA5; } } void op_add_rsp(int num){ //スタックポインタの加算(pop方向) //add rsp,num if(0xFFFFFF80&num){ OpBuffer[obp++]=(char)0x48; OpBuffer[obp++]=(char)0x81; OpBuffer[obp++]=(char)0xC4; *((long *)(OpBuffer+obp))=num; obp+=sizeof(long); } else{ //「-128 < num < 127」の場合 OpBuffer[obp++]=(char)0x48; OpBuffer[obp++]=(char)0x83; OpBuffer[obp++]=(char)0xC4; OpBuffer[obp++]=(char)num; } } void op_sub_rsp(int num){ //スタックポインタの減算(push方向) //sub rsp,num if(0xFFFFFF80&num){ OpBuffer[obp++]=(char)0x48; OpBuffer[obp++]=(char)0x81; OpBuffer[obp++]=(char)0xEC; *((long *)(OpBuffer+obp))=num; obp+=sizeof(long); } else{ //「-128 < num < 127」の場合 OpBuffer[obp++]=(char)0x48; OpBuffer[obp++]=(char)0x83; OpBuffer[obp++]=(char)0xEC; OpBuffer[obp++]=(char)num; } } void op_add_esp(int num){ //スタックポインタの加算(pop方向) //add esp,num if(0xFFFFFF80&num){ OpBuffer[obp++]=(char)0x81; OpBuffer[obp++]=(char)0xC4; *((long *)(OpBuffer+obp))=num; obp+=sizeof(long); } else{ //「-128 < num < 127」の場合 OpBuffer[obp++]=(char)0x83; OpBuffer[obp++]=(char)0xC4; OpBuffer[obp++]=(char)num; } } void op_sub_esp(int num){ //スタックポインタの減算(push方向) //sub esp,num if(0xFFFFFF80&num){ OpBuffer[obp++]=(char)0x81; OpBuffer[obp++]=(char)0xEC; *((long *)(OpBuffer+obp))=num; obp+=sizeof(long); } else{ //「-128 < num < 127」の場合 OpBuffer[obp++]=(char)0x83; OpBuffer[obp++]=(char)0xEC; OpBuffer[obp++]=(char)num; } } ////////////////////////////// // 浮動小数点関連 ////////////////////////////// void op_fld_ptr_esp(int type){ //スタックポインタが示すバッファのデータを浮動小数点レジスタへロード if(type==DEF_DOUBLE){ //fld qword ptr[esp] OpBuffer[obp++]=(char)0xDD; OpBuffer[obp++]=(char)0x04; OpBuffer[obp++]=(char)0x24; } else if(type==DEF_SINGLE){ //fld dword ptr[esp] OpBuffer[obp++]=(char)0xD9; OpBuffer[obp++]=(char)0x04; OpBuffer[obp++]=(char)0x24; } else if(type==DEF_INT64){ //fild qword ptr[esp] OpBuffer[obp++]=(char)0xDF; OpBuffer[obp++]=(char)0x2C; OpBuffer[obp++]=(char)0x24; } else if(type==DEF_LONG){ //fild dword ptr[esp] OpBuffer[obp++]=(char)0xDB; OpBuffer[obp++]=(char)0x04; OpBuffer[obp++]=(char)0x24; } } ////////////////////////////// // レジスタ関連 ////////////////////////////// void op_zero_reg(int reg){ //レジスタに0をセット if(REG_RAX<=reg&®<=REG_RDI){ /* rax〜rdi 0100 1000 0011 0011 11 xxx xxx */ OpBuffer[obp++]=(char)0x48; OpBuffer[obp++]=(char)0x33; OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(reg)); } if(REG_R8<=reg&®<=REG_R15){ /* r8〜r15 0100 1101 0011 0011 11 xxx xxx */ OpBuffer[obp++]=(char)0x4D; OpBuffer[obp++]=(char)0x33; OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(reg)); } } ///////////////////////////// // 関数呼び出し ///////////////////////////// void op_call(SUBINFO *psi){ OpBuffer[obp++]=(char)0xE8; pobj_SubAddrSchedule->add(psi,1); psi->bUse=1; obp+=sizeof(long); }