?? ops.c
字號:
destreg = DECODE_RM_LONG_REGISTER(rh); DECODE_PRINTF(","); srcval = fetch_data_long(srcoffset); imm = fetch_long_imm(); DECODE_PRINTF2(",%d\n", (s32)imm); TRACE_AND_STEP(); imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) || (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) { CLEAR_FLAG(F_CF); CLEAR_FLAG(F_OF); } else { SET_FLAG(F_CF); SET_FLAG(F_OF); } *destreg = (u32)res_lo; } else { u16 *destreg; u16 srcval; u32 res; s16 imm; destreg = DECODE_RM_WORD_REGISTER(rh); DECODE_PRINTF(","); srcval = fetch_data_word(srcoffset); imm = fetch_word_imm(); DECODE_PRINTF2(",%d\n", (s32)imm); TRACE_AND_STEP(); res = (s16)srcval * (s16)imm; if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) || (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) { CLEAR_FLAG(F_CF); CLEAR_FLAG(F_OF); } else { SET_FLAG(F_CF); SET_FLAG(F_OF); } *destreg = (u16)res; } } else { /* register to register */ if (M.x86.mode & SYSMODE_PREFIX_DATA) { u32 *destreg,*srcreg; u32 res_lo,res_hi; s32 imm; destreg = DECODE_RM_LONG_REGISTER(rh); DECODE_PRINTF(","); srcreg = DECODE_RM_LONG_REGISTER(rl); imm = fetch_long_imm(); DECODE_PRINTF2(",%d\n", (s32)imm); TRACE_AND_STEP(); imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm); if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) || (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) { CLEAR_FLAG(F_CF); CLEAR_FLAG(F_OF); } else { SET_FLAG(F_CF); SET_FLAG(F_OF); } *destreg = (u32)res_lo; } else { u16 *destreg,*srcreg; u32 res; s16 imm; destreg = DECODE_RM_WORD_REGISTER(rh); DECODE_PRINTF(","); srcreg = DECODE_RM_WORD_REGISTER(rl); imm = fetch_word_imm(); DECODE_PRINTF2(",%d\n", (s32)imm); res = (s16)*srcreg * (s16)imm; if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) || (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) { CLEAR_FLAG(F_CF); CLEAR_FLAG(F_OF); } else { SET_FLAG(F_CF); SET_FLAG(F_OF); } *destreg = (u16)res; } } DECODE_CLEAR_SEGOVR(); END_OF_INSTR();}/****************************************************************************REMARKS:Handles opcode 0x6a****************************************************************************/void x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1)){ s16 imm; START_OF_INSTR(); imm = (s8)fetch_byte_imm(); DECODE_PRINTF2("PUSH\t%d\n", imm); TRACE_AND_STEP(); push_word(imm); DECODE_CLEAR_SEGOVR(); END_OF_INSTR();}/****************************************************************************REMARKS:Handles opcode 0x6b****************************************************************************/void x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1)){ int mod, rl, rh; uint srcoffset; s8 imm; START_OF_INSTR(); DECODE_PRINTF("IMUL\t"); FETCH_DECODE_MODRM(mod, rh, rl); if (mod < 3) { srcoffset = decode_rmXX_address(mod, rl); if (M.x86.mode & SYSMODE_PREFIX_DATA) { u32 *destreg; u32 srcval; u32 res_lo,res_hi; destreg = DECODE_RM_LONG_REGISTER(rh); DECODE_PRINTF(","); srcval = fetch_data_long(srcoffset); imm = fetch_byte_imm(); DECODE_PRINTF2(",%d\n", (s32)imm); TRACE_AND_STEP(); imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) || (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) { CLEAR_FLAG(F_CF); CLEAR_FLAG(F_OF); } else { SET_FLAG(F_CF); SET_FLAG(F_OF); } *destreg = (u32)res_lo; } else { u16 *destreg; u16 srcval; u32 res; destreg = DECODE_RM_WORD_REGISTER(rh); DECODE_PRINTF(","); srcval = fetch_data_word(srcoffset); imm = fetch_byte_imm(); DECODE_PRINTF2(",%d\n", (s32)imm); TRACE_AND_STEP(); res = (s16)srcval * (s16)imm; if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) || (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) { CLEAR_FLAG(F_CF); CLEAR_FLAG(F_OF); } else { SET_FLAG(F_CF); SET_FLAG(F_OF); } *destreg = (u16)res; } } else { /* register to register */ if (M.x86.mode & SYSMODE_PREFIX_DATA) { u32 *destreg,*srcreg; u32 res_lo,res_hi; destreg = DECODE_RM_LONG_REGISTER(rh); DECODE_PRINTF(","); srcreg = DECODE_RM_LONG_REGISTER(rl); imm = fetch_byte_imm(); DECODE_PRINTF2(",%d\n", (s32)imm); TRACE_AND_STEP(); imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm); if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) || (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) { CLEAR_FLAG(F_CF); CLEAR_FLAG(F_OF); } else { SET_FLAG(F_CF); SET_FLAG(F_OF); } *destreg = (u32)res_lo; } else { u16 *destreg,*srcreg; u32 res; destreg = DECODE_RM_WORD_REGISTER(rh); DECODE_PRINTF(","); srcreg = DECODE_RM_WORD_REGISTER(rl); imm = fetch_byte_imm(); DECODE_PRINTF2(",%d\n", (s32)imm); TRACE_AND_STEP(); res = (s16)*srcreg * (s16)imm; if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) || (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) { CLEAR_FLAG(F_CF); CLEAR_FLAG(F_OF); } else { SET_FLAG(F_CF); SET_FLAG(F_OF); } *destreg = (u16)res; } } DECODE_CLEAR_SEGOVR(); END_OF_INSTR();}/****************************************************************************REMARKS:Handles opcode 0x6c****************************************************************************/void x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1)){ START_OF_INSTR(); DECODE_PRINTF("INSB\n"); ins(1); TRACE_AND_STEP(); DECODE_CLEAR_SEGOVR(); END_OF_INSTR();}/****************************************************************************REMARKS:Handles opcode 0x6d****************************************************************************/void x86emuOp_ins_word(u8 X86EMU_UNUSED(op1)){ START_OF_INSTR(); if (M.x86.mode & SYSMODE_PREFIX_DATA) { DECODE_PRINTF("INSD\n"); ins(4); } else { DECODE_PRINTF("INSW\n"); ins(2); } TRACE_AND_STEP(); DECODE_CLEAR_SEGOVR(); END_OF_INSTR();}/****************************************************************************REMARKS:Handles opcode 0x6e****************************************************************************/void x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1)){ START_OF_INSTR(); DECODE_PRINTF("OUTSB\n"); outs(1); TRACE_AND_STEP(); DECODE_CLEAR_SEGOVR(); END_OF_INSTR();}/****************************************************************************REMARKS:Handles opcode 0x6f****************************************************************************/void x86emuOp_outs_word(u8 X86EMU_UNUSED(op1)){ START_OF_INSTR(); if (M.x86.mode & SYSMODE_PREFIX_DATA) { DECODE_PRINTF("OUTSD\n"); outs(4); } else { DECODE_PRINTF("OUTSW\n"); outs(2); } TRACE_AND_STEP(); DECODE_CLEAR_SEGOVR(); END_OF_INSTR();}/****************************************************************************REMARKS:Handles opcode 0x70 - 0x7F****************************************************************************/int x86emu_check_jump_condition(u8 op);void x86emuOp_jump_near_cond(u8 op1){ s8 offset; u16 target; int cond; /* jump to byte offset if overflow flag is set */ START_OF_INSTR(); cond = x86emu_check_jump_condition(op1 & 0xF); offset = (s8)fetch_byte_imm(); target = (u16)(M.x86.R_IP + (s16)offset); DECODE_PRINTF2("%x\n", target); TRACE_AND_STEP(); if (cond) M.x86.R_IP = target; DECODE_CLEAR_SEGOVR(); END_OF_INSTR();}/****************************************************************************REMARKS:Handles opcode 0x80****************************************************************************/void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1)){ int mod, rl, rh; u8 *destreg; uint destoffset; u8 imm; u8 destval; /* * Weirdo special case instruction format. Part of the opcode * held below in "RH". Doubly nested case would result, except * that the decoded instruction */ START_OF_INSTR(); FETCH_DECODE_MODRM(mod, rh, rl);#ifdef DEBUG if (DEBUG_DECODE()) { /* XXX DECODE_PRINTF may be changed to something more general, so that it is important to leave the strings in the same format, even though the result is that the above test is done twice. */ switch (rh) { case 0: DECODE_PRINTF("ADD\t"); break; case 1: DECODE_PRINTF("OR\t"); break; case 2: DECODE_PRINTF("ADC\t"); break; case 3: DECODE_PRINTF("SBB\t"); break; case 4: DECODE_PRINTF("AND\t"); break; case 5: DECODE_PRINTF("SUB\t"); break; case 6: DECODE_PRINTF("XOR\t"); break; case 7: DECODE_PRINTF("CMP\t"); break; } }#endif /* know operation, decode the mod byte to find the addressing mode. */ if (mod < 3) { DECODE_PRINTF("BYTE PTR "); destoffset = decode_rmXX_address(mod, rl); DECODE_PRINTF(","); destval = fetch_data_byte(destoffset); imm = fetch_byte_imm(); DECODE_PRINTF2("%x\n", imm); TRACE_AND_STEP(); destval = (*genop_byte_operation[rh]) (destval, imm); if (rh != 7) store_data_byte(destoffset, destval); } else { /* register to register */ destreg = DECODE_RM_BYTE_REGISTER(rl); DECODE_PRINTF(","); imm = fetch_byte_imm(); DECODE_PRINTF2("%x\n", imm); TRACE_AND_STEP(); destval = (*genop_byte_operation[rh]) (*destreg, imm); if (rh != 7) *destreg = destval; } DECODE_CLEAR_SEGOVR(); END_OF_INSTR();}/****************************************************************************REMARKS:Handles opcode 0x81****************************************************************************/void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1)){ int mod, rl, rh; uint destoffset; /* * Weirdo special case instruction format. Part of the opcode * held below in "RH". Doubly nested case would result, except * that the decoded instruction */ START_OF_INSTR(); FETCH_DECODE_MODRM(mod, rh, rl);#ifdef DEBUG if (DEBUG_DECODE()) { /* XXX DECODE_PRINTF may be changed to something more general, so that it is important to leave the strings in the same format, even though the result is that the above test is done twice. */ switch (rh) { case 0: DECODE_PRINTF("ADD\t"); break; case 1: DECODE_PRINTF("OR\t"); break; case 2: DECODE_PRINTF("ADC\t"); break; case 3: DECODE_PRINTF("SBB\t"); break; case 4: DECODE_PRINTF("AND\t"); break; case 5: DECODE_PRINTF("SUB\t"); break; case 6: DECODE_PRINTF("XOR\t"); break; case 7: DECODE_PRINTF("CMP\t"); break; } }#endif /* * Know operation, decode the mod byte to find the addressing * mode. */ if (mod < 3) { DECODE_PRINTF("DWORD PTR "); destoffset = decode_rmXX_address(mod, rl); if (M.x86.mode & SYSMODE_PREFIX_DATA) { u32 destval,imm; DECODE_PRINTF(","); destval = fetch_data_long(destoffset); imm = fetch_long_imm(); DECODE_PRINTF2("%x\n", imm); TRACE_AND_STEP(); destval = (*genop_long_operation[rh]) (destval, imm); if (rh != 7) store_data_long(destoffset, destval); } else { u16 destval,imm; DECODE_PRINTF(","); destval = fetch_data_word(destoffset); imm = fetch_word_imm(); DECODE_PRINTF2("%x\n", imm); TRACE_AND_STEP(); destval = (*genop_word_operation[rh]) (destval, imm); if (rh != 7) store_data_word(destoffset, destval); } } else { /* register to register */ if (M.x86.mode & SYSMODE_PREFIX_DATA) { u32 *destreg; u32 destval,imm; destreg = DECODE_RM_LONG_REGISTER(rl); DECODE_PRINTF(","); imm = fetch_long_imm(); DECODE_PRINTF2("%x\n", imm); TRACE_AND_STEP(); destval = (*genop_long_operation[rh]) (*destreg, imm); if (rh != 7) *destreg = destval; } else { u16 *destreg; u16 destval,imm; destreg = DECODE_RM_WORD_REGISTER(rl); DECODE_PRINTF(","); imm = fetch_word_imm(); DECODE_PRINTF2("%x\n", imm); TRACE_AND_STEP(); destval = (*genop_word_operation[rh]) (*destreg, imm);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -