📄 decoder.h
字号:
cache_addb(0xe8); cache_addd(((Bit32u)&mem_writed_checked_x86) - (Bit32u)cache.pos-4); cache_addw(0xc483); // add esp,8 cache_addb(0x08); cache_addw(0x012c); // sub al,1 cache_addb(0x5a); // pop edx // Restore registers to be used again x86gen.regs[X86_REG_EAX]->notusable=false; x86gen.regs[X86_REG_ECX]->notusable=false; dyn_check_bool_exception_ne(); gen_fill_jump(jmp_loc); } else { gen_protectflags(); gen_call_function((void *)&mem_writew_checked_x86,"%Ddr%Dd",addr,val); dyn_check_bool_exception_al(); }}#endifstatic void dyn_push_unchecked(DynReg * dynreg) { gen_protectflags(); gen_lea(DREG(STACK),DREG(ESP),0,0,decode.big_op?(-4):(-2)); gen_dop_word_var(DOP_AND,true,DREG(STACK),&cpu.stack.mask); gen_dop_word_var(DOP_AND,true,DREG(ESP),&cpu.stack.notmask); gen_dop_word(DOP_OR,true,DREG(ESP),DREG(STACK)); gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS)); if (decode.big_op) { gen_call_function((void *)&mem_writed,"%Drd%Dd",DREG(STACK),dynreg); } else { //Can just push the whole 32-bit word as operand gen_call_function((void *)&mem_writew,"%Drd%Dd",DREG(STACK),dynreg); }}static void dyn_push(DynReg * dynreg) { gen_protectflags(); gen_lea(DREG(STACK),DREG(ESP),0,0,decode.big_op?(-4):(-2)); gen_dop_word(DOP_MOV,true,DREG(NEWESP),DREG(ESP)); gen_dop_word_var(DOP_AND,true,DREG(STACK),&cpu.stack.mask); gen_dop_word_var(DOP_AND,true,DREG(NEWESP),&cpu.stack.notmask); gen_dop_word(DOP_OR,true,DREG(NEWESP),DREG(STACK)); gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS)); if (decode.big_op) { gen_call_function((void *)&mem_writed_checked_x86,"%Drd%Dd",DREG(STACK),dynreg); } else { //Can just push the whole 32-bit word as operand gen_call_function((void *)&mem_writew_checked_x86,"%Drd%Dd",DREG(STACK),dynreg); } dyn_check_bool_exception_al(); /* everything was ok, change register now */ gen_dop_word(DOP_MOV,true,DREG(ESP),DREG(NEWESP)); gen_releasereg(DREG(NEWESP));}static void dyn_pop(DynReg * dynreg,bool checked=true) { gen_protectflags(); gen_dop_word(DOP_MOV,true,DREG(STACK),DREG(ESP)); gen_dop_word_var(DOP_AND,true,DREG(STACK),&cpu.stack.mask); gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS)); if (checked) { if (decode.big_op) { gen_call_function((void *)&mem_readd_checked_x86,"%Drd%Id",DREG(STACK),&core_dyn.readdata); } else { gen_call_function((void *)&mem_readw_checked_x86,"%Drd%Id",DREG(STACK),&core_dyn.readdata); } dyn_check_bool_exception_al(); gen_mov_host(&core_dyn.readdata,dynreg,decode.big_op?4:2); } else { if (decode.big_op) { gen_call_function((void *)&mem_readd,"%Rd%Drd",dynreg,DREG(STACK)); } else { gen_call_function((void *)&mem_readw,"%Rw%Drd",dynreg,DREG(STACK)); } } if (dynreg!=DREG(ESP)) { gen_lea(DREG(STACK),DREG(ESP),0,0,decode.big_op?4:2); gen_dop_word_var(DOP_AND,true,DREG(STACK),&cpu.stack.mask); gen_dop_word_var(DOP_AND,true,DREG(ESP),&cpu.stack.notmask); gen_dop_word(DOP_OR,true,DREG(ESP),DREG(STACK)); }}static void INLINE dyn_get_modrm(void) { decode.modrm.val=decode_fetchb(); decode.modrm.mod=(decode.modrm.val >> 6) & 3; decode.modrm.reg=(decode.modrm.val >> 3) & 7; decode.modrm.rm=(decode.modrm.val & 7);}static void dyn_fill_ea(bool addseg=true, DynReg * reg_ea=DREG(EA)) { DynReg * segbase; if (!decode.big_addr) { Bits imm; switch (decode.modrm.mod) { case 0:imm=0;break; case 1:imm=(Bit8s)decode_fetchb();break; case 2:imm=(Bit16s)decode_fetchw();break; } DynReg * extend_src=reg_ea; switch (decode.modrm.rm) { case 0:/* BX+SI */ gen_lea(reg_ea,DREG(EBX),DREG(ESI),0,imm); segbase=DREG(DS); break; case 1:/* BX+DI */ gen_lea(reg_ea,DREG(EBX),DREG(EDI),0,imm); segbase=DREG(DS); break; case 2:/* BP+SI */ gen_lea(reg_ea,DREG(EBP),DREG(ESI),0,imm); segbase=DREG(SS); break; case 3:/* BP+DI */ gen_lea(reg_ea,DREG(EBP),DREG(EDI),0,imm); segbase=DREG(SS); break; case 4:/* SI */ if (imm) gen_lea(reg_ea,DREG(ESI),0,0,imm); else extend_src=DREG(ESI); segbase=DREG(DS); break; case 5:/* DI */ if (imm) gen_lea(reg_ea,DREG(EDI),0,0,imm); else extend_src=DREG(EDI); segbase=DREG(DS); break; case 6:/* imm/BP */ if (!decode.modrm.mod) { imm=decode_fetchw(); gen_dop_word_imm(DOP_MOV,true,reg_ea,imm); segbase=DREG(DS); goto skip_extend_word; } else { gen_lea(reg_ea,DREG(EBP),0,0,imm); segbase=DREG(SS); } break; case 7: /* BX */ if (imm) gen_lea(reg_ea,DREG(EBX),0,0,imm); else extend_src=DREG(EBX); segbase=DREG(DS); break; } gen_extend_word(false,reg_ea,extend_src);skip_extend_word: if (addseg) { gen_lea(reg_ea,reg_ea,decode.segprefix ? decode.segprefix : segbase,0,0); } } else { Bits imm=0; DynReg * base=0;DynReg * scaled=0;Bitu scale=0; switch (decode.modrm.rm) { case 0:base=DREG(EAX);segbase=DREG(DS);break; case 1:base=DREG(ECX);segbase=DREG(DS);break; case 2:base=DREG(EDX);segbase=DREG(DS);break; case 3:base=DREG(EBX);segbase=DREG(DS);break; case 4: /* SIB */ { Bitu sib=decode_fetchb(); static DynReg * scaledtable[8]={ DREG(EAX),DREG(ECX),DREG(EDX),DREG(EBX), 0,DREG(EBP),DREG(ESI),DREG(EDI), }; scaled=scaledtable[(sib >> 3) &7]; scale=(sib >> 6); switch (sib & 7) { case 0:base=DREG(EAX);segbase=DREG(DS);break; case 1:base=DREG(ECX);segbase=DREG(DS);break; case 2:base=DREG(EDX);segbase=DREG(DS);break; case 3:base=DREG(EBX);segbase=DREG(DS);break; case 4:base=DREG(ESP);segbase=DREG(SS);break; case 5: if (decode.modrm.mod) { base=DREG(EBP);segbase=DREG(SS); } else { segbase=DREG(DS); Bitu val; if (decode_fetchd_imm(val)) { gen_mov_host((void*)val,DREG(EA),4); if (!addseg) { gen_lea(reg_ea,DREG(EA),scaled,scale,0); } else { DynReg** seg = decode.segprefix ? &decode.segprefix : &segbase; gen_lea(DREG(EA),DREG(EA),scaled,scale,0); gen_lea(reg_ea,DREG(EA),*seg,0,0); } return; } imm=(Bit32s)val; } break; case 6:base=DREG(ESI);segbase=DREG(DS);break; case 7:base=DREG(EDI);segbase=DREG(DS);break; } } break; /* SIB Break */ case 5: if (decode.modrm.mod) { base=DREG(EBP);segbase=DREG(SS); } else { imm=(Bit32s)decode_fetchd();segbase=DREG(DS); } break; case 6:base=DREG(ESI);segbase=DREG(DS);break; case 7:base=DREG(EDI);segbase=DREG(DS);break; } switch (decode.modrm.mod) { case 1:imm=(Bit8s)decode_fetchb();break; case 2: { Bitu val; if (decode_fetchd_imm(val)) { gen_mov_host((void*)val,DREG(EA),4); if (!addseg) { gen_lea(DREG(EA),DREG(EA),scaled,scale,0); gen_lea(reg_ea,DREG(EA),base,0,0); } else { DynReg** seg = decode.segprefix ? &decode.segprefix : &segbase; if (!base) { gen_lea(DREG(EA),DREG(EA),scaled,scale,0); gen_lea(reg_ea,DREG(EA),*seg,0,0); } else if (!scaled) { gen_lea(DREG(EA),DREG(EA),*seg,0,0); gen_lea(reg_ea,DREG(EA),base,0,0); } else { gen_lea(DREG(EA),DREG(EA),scaled,scale,0); gen_lea(DREG(EA),DREG(EA),base,0,0); gen_lea(reg_ea,DREG(EA),decode.segprefix ? decode.segprefix : segbase,0,0); } } return; } imm=(Bit32s)val; break; } } if (!addseg) { gen_lea(reg_ea,base,scaled,scale,imm); } else { DynReg** seg = decode.segprefix ? &decode.segprefix : &segbase; if (!base) gen_lea(reg_ea,*seg,scaled,scale,imm); else if (!scaled) gen_lea(reg_ea,base,*seg,0,imm); else { gen_lea(DREG(EA),base,scaled,scale,imm); gen_lea(reg_ea,DREG(EA),decode.segprefix ? decode.segprefix : segbase,0,0); } } }}static void dyn_dop_word_imm(DualOps op,bool dword,DynReg * dr1) { Bitu val; if (dword) { if (decode_fetchd_imm(val)) { gen_dop_word_imm_mem(op,true,dr1,(void*)val); return; } } else { if (decode_fetchw_imm(val)) { gen_dop_word_imm_mem(op,false,dr1,(void*)val); return; } } gen_dop_word_imm(op,dword,dr1,val);}static void dyn_dop_byte_imm(DualOps op,DynReg * dr1,Bit8u di1) { Bitu val; if (decode_fetchb_imm(val)) { gen_dop_byte_imm_mem(op,dr1,di1,(void*)val); } else { gen_dop_byte_imm(op,dr1,di1,(Bit8u)val); }}#include "helpers.h"#include "string.h"static void dyn_dop_ebgb(DualOps op) { dyn_get_modrm();DynReg * rm_reg=&DynRegs[decode.modrm.reg&3]; if (decode.modrm.mod<3) { dyn_fill_ea(); if ((op<=DOP_TEST) && (op!=DOP_ADC && op!=DOP_SBB)) set_skipflags(true); dyn_read_byte(DREG(EA),DREG(TMPB),false); if (op<=DOP_TEST) { if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); else set_skipflags(false); } gen_dop_byte(op,DREG(TMPB),0,rm_reg,decode.modrm.reg&4); if (op!=DOP_CMP) dyn_write_byte_release(DREG(EA),DREG(TMPB),false); else gen_releasereg(DREG(EA)); gen_releasereg(DREG(TMPB)); } else { if (op<=DOP_TEST) { if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); else gen_discardflags(); } gen_dop_byte(op,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,rm_reg,decode.modrm.reg&4); }}static void dyn_dop_gbeb(DualOps op) { dyn_get_modrm();DynReg * rm_reg=&DynRegs[decode.modrm.reg&3]; if (decode.modrm.mod<3) { dyn_fill_ea(); if ((op<=DOP_TEST) && (op!=DOP_ADC && op!=DOP_SBB)) set_skipflags(true); dyn_read_byte_release(DREG(EA),DREG(TMPB),false); if (op<=DOP_TEST) { if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); else set_skipflags(false); } gen_dop_byte(op,rm_reg,decode.modrm.reg&4,DREG(TMPB),0); gen_releasereg(DREG(TMPB)); } else { if (op<=DOP_TEST) { if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); else gen_discardflags(); } gen_dop_byte(op,rm_reg,decode.modrm.reg&4,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); }}static void dyn_mov_ebib(void) { dyn_get_modrm(); if (decode.modrm.mod<3) { dyn_fill_ea(); gen_call_write(DREG(EA),decode_fetchb(),1); dyn_check_bool_exception_al(); } else { gen_dop_byte_imm(DOP_MOV,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,decode_fetchb()); }}static void dyn_mov_ebgb(void) { dyn_get_modrm(); DynReg * rm_reg=&DynRegs[decode.modrm.reg&3];Bitu rm_regi=decode.modrm.reg&4; if (decode.modrm.mod<3) { dyn_fill_ea(); dyn_write_byte_release(DREG(EA),rm_reg,rm_regi); } else { gen_dop_byte(DOP_MOV,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,rm_reg,rm_regi); }}static void dyn_mov_gbeb(void) { dyn_get_modrm(); DynReg * rm_reg=&DynRegs[decode.modrm.reg&3];Bitu rm_regi=decode.modrm.reg&4; if (decode.modrm.mod<3) { dyn_fill_ea(); dyn_read_byte_release(DREG(EA),rm_reg,rm_regi); } else { gen_dop_byte(DOP_MOV,rm_reg,rm_regi,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); }}static void dyn_dop_evgv(DualOps op) { dyn_get_modrm(); DynReg * rm_reg=&DynRegs[decode.modrm.reg]; if (decode.modrm.mod<3) { dyn_fill_ea(); if ((op<=DOP_TEST) && (op!=DOP_ADC && op!=DOP_SBB)) set_skipflags(true); dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); if (op<=DOP_TEST) { if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); else set_skipflags(false); } gen_dop_word(op,decode.big_op,DREG(TMPW),rm_reg); if (op!=DOP_CMP) dyn_write_word_release(DREG(EA),DREG(TMPW),decode.big_op); else gen_releasereg(DREG(EA)); gen_releasereg(DREG(TMPW)); } else { if (op<=DOP_TEST) { if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); else gen_discardflags(); } gen_dop_word(op,decode.big_op,&DynRegs[decode.modrm.rm],rm_reg); }}static void dyn_imul_gvev(Bitu immsize) { dyn_get_modrm();DynReg * src; DynReg * rm_reg=&DynRegs[decode.modrm.reg]; if (decode.modrm.mod<3) { dyn_fill_ea();dyn_read_word_release(DREG(EA),DREG(TMPW),decode.big_op); src=DREG(TMPW); } else { src=&DynRegs[decode.modrm.rm]; } gen_needflags(); switch (immsize) { case 0:gen_imul_word(decode.big_op,rm_reg,src);break; case 1:gen_imul_word_imm(decode.big_op,rm_reg,src,(Bit8s)decode_fetchb());break; case 2:gen_imul_word_imm(decode.big_op,rm_reg,src,(Bit16s)decode_fetchw());break; case 4:gen_imul_word_imm(decode.big_op,rm_reg,src,(Bit32s)decode_fetchd());break; } gen_releasereg(DREG(TMPW));}static void dyn_dop_gvev(DualOps op) { dyn_get_modrm(); DynReg * rm_reg=&DynRegs[decode.modrm.reg]; if (decode.modrm.mod<3) { dyn_fill_ea(); if ((op<=DOP_TEST) && (op!=DOP_ADC && op!=DOP_SBB)) set_skipflags(true); dyn_read_word_release(DREG(EA),DREG(TMPW),decode.big_op); if (op<=DOP_TEST) { if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); else set_skipflags(false); } gen_dop_word(op,decode.big_op,rm_reg,DREG(TMPW));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -