📄 decode.c
字号:
{#ifdef DEBUG if (CHECK_DATA_ACCESS()) x86emu_check_data_access(segment, offset);#endif (*sys_wrb)(((u32)segment << 4) + offset, val);}/****************************************************************************PARAMETERS:segment - Segment to store data atoffset - Offset to store data atval - Value to storeREMARKS:Writes a word value to an absolute memory location.NOTE: Do not inline this function as (*sys_wrX) is already inline!****************************************************************************/void store_data_word_abs( uint segment, uint offset, u16 val){#ifdef DEBUG if (CHECK_DATA_ACCESS()) x86emu_check_data_access(segment, offset);#endif (*sys_wrw)(((u32)segment << 4) + offset, val);}/****************************************************************************PARAMETERS:segment - Segment to store data atoffset - Offset to store data atval - Value to storeREMARKS:Writes a long value to an absolute memory location.NOTE: Do not inline this function as (*sys_wrX) is already inline!****************************************************************************/void store_data_long_abs( uint segment, uint offset, u32 val){#ifdef DEBUG if (CHECK_DATA_ACCESS()) x86emu_check_data_access(segment, offset);#endif (*sys_wrl)(((u32)segment << 4) + offset, val);}/****************************************************************************PARAMETERS:reg - Register to decodeRETURNS:Pointer to the appropriate registerREMARKS:Return a pointer to the register given by the R/RM field of themodrm byte, for byte operands. Also enables the decoding of instructions.****************************************************************************/u8* decode_rm_byte_register( int reg){ switch (reg) { case 0: DECODE_PRINTF("AL"); return &M.x86.R_AL; case 1: DECODE_PRINTF("CL"); return &M.x86.R_CL; case 2: DECODE_PRINTF("DL"); return &M.x86.R_DL; case 3: DECODE_PRINTF("BL"); return &M.x86.R_BL; case 4: DECODE_PRINTF("AH"); return &M.x86.R_AH; case 5: DECODE_PRINTF("CH"); return &M.x86.R_CH; case 6: DECODE_PRINTF("DH"); return &M.x86.R_DH; case 7: DECODE_PRINTF("BH"); return &M.x86.R_BH; } HALT_SYS(); return NULL; /* NOT REACHED OR REACHED ON ERROR */}/****************************************************************************PARAMETERS:reg - Register to decodeRETURNS:Pointer to the appropriate registerREMARKS:Return a pointer to the register given by the R/RM field of themodrm byte, for word operands. Also enables the decoding of instructions.****************************************************************************/u16* decode_rm_word_register( int reg){ switch (reg) { case 0: DECODE_PRINTF("AX"); return &M.x86.R_AX; case 1: DECODE_PRINTF("CX"); return &M.x86.R_CX; case 2: DECODE_PRINTF("DX"); return &M.x86.R_DX; case 3: DECODE_PRINTF("BX"); return &M.x86.R_BX; case 4: DECODE_PRINTF("SP"); return &M.x86.R_SP; case 5: DECODE_PRINTF("BP"); return &M.x86.R_BP; case 6: DECODE_PRINTF("SI"); return &M.x86.R_SI; case 7: DECODE_PRINTF("DI"); return &M.x86.R_DI; } HALT_SYS(); return NULL; /* NOTREACHED OR REACHED ON ERROR */}/****************************************************************************PARAMETERS:reg - Register to decodeRETURNS:Pointer to the appropriate registerREMARKS:Return a pointer to the register given by the R/RM field of themodrm byte, for dword operands. Also enables the decoding of instructions.****************************************************************************/u32* decode_rm_long_register( int reg){ switch (reg) { case 0: DECODE_PRINTF("EAX"); return &M.x86.R_EAX; case 1: DECODE_PRINTF("ECX"); return &M.x86.R_ECX; case 2: DECODE_PRINTF("EDX"); return &M.x86.R_EDX; case 3: DECODE_PRINTF("EBX"); return &M.x86.R_EBX; case 4: DECODE_PRINTF("ESP"); return &M.x86.R_ESP; case 5: DECODE_PRINTF("EBP"); return &M.x86.R_EBP; case 6: DECODE_PRINTF("ESI"); return &M.x86.R_ESI; case 7: DECODE_PRINTF("EDI"); return &M.x86.R_EDI; } HALT_SYS(); return NULL; /* NOTREACHED OR REACHED ON ERROR */}/****************************************************************************PARAMETERS:reg - Register to decodeRETURNS:Pointer to the appropriate registerREMARKS:Return a pointer to the register given by the R/RM field of themodrm byte, for word operands, modified from above for the weirdospecial case of segreg operands. Also enables the decoding of instructions.****************************************************************************/u16* decode_rm_seg_register( int reg){ switch (reg) { case 0: DECODE_PRINTF("ES"); return &M.x86.R_ES; case 1: DECODE_PRINTF("CS"); return &M.x86.R_CS; case 2: DECODE_PRINTF("SS"); return &M.x86.R_SS; case 3: DECODE_PRINTF("DS"); return &M.x86.R_DS; case 4: case 5: case 6: case 7: DECODE_PRINTF("ILLEGAL SEGREG"); break; } HALT_SYS(); return NULL; /* NOT REACHED OR REACHED ON ERROR */}/****************************************************************************PARAMETERS:rm - RM value to decodeRETURNS:Offset in memory for the address decodingREMARKS:Return the offset given by mod=00 addressing. Also enables thedecoding of instructions.NOTE: The code which specifies the corresponding segment (ds vs ss) below in the case of [BP+..]. The assumption here is that at the point that this subroutine is called, the bit corresponding to SYSMODE_SEG_DS_SS will be zero. After every instruction except the segment override instructions, this bit (as well as any bits indicating segment overrides) will be clear. So if a SS access is needed, set this bit. Otherwise, DS access occurs (unless any of the segment override bits are set).****************************************************************************/unsigned decode_rm00_address( int rm){ unsigned offset; if (M.x86.mode & SYSMODE_PREFIX_ADDR) { switch (rm) { case 0: DECODE_PRINTF("[EAX]"); return M.x86.R_EAX; case 1: DECODE_PRINTF("[ECX]"); return M.x86.R_ECX; case 2: DECODE_PRINTF("[EDX]");/* M.x86.mode |= SYSMODE_SEG_DS_SS; */ return M.x86.R_EDX; case 3: DECODE_PRINTF("[EBX]");/* M.x86.mode |= SYSMODE_SEG_DS_SS; */ return M.x86.R_EBX; case 4: printk("Unsupported SIB encoding\n"); HALT_SYS(); return 0; case 5: offset = fetch_long_imm(); DECODE_PRINTF2("[%08x]", offset); return offset; case 6: DECODE_PRINTF("[ESI]"); return M.x86.R_ESI; case 7: DECODE_PRINTF("[EDI]"); return M.x86.R_EDI; } } else { switch (rm) { case 0: DECODE_PRINTF("[BX+SI]"); return M.x86.R_BX + M.x86.R_SI; case 1: DECODE_PRINTF("[BX+DI]"); return M.x86.R_BX + M.x86.R_DI; case 2: DECODE_PRINTF("[BP+SI]"); M.x86.mode |= SYSMODE_SEG_DS_SS; return M.x86.R_BP + M.x86.R_SI; case 3: DECODE_PRINTF("[BP+DI]"); M.x86.mode |= SYSMODE_SEG_DS_SS; return M.x86.R_BP + M.x86.R_DI; case 4: DECODE_PRINTF("[SI]"); return M.x86.R_SI; case 5: DECODE_PRINTF("[DI]"); return M.x86.R_DI; case 6: offset = fetch_word_imm(); DECODE_PRINTF2("[%04x]", offset); return offset; case 7: DECODE_PRINTF("[BX]"); return M.x86.R_BX; } } HALT_SYS(); return 0;}/****************************************************************************PARAMETERS:rm - RM value to decodeRETURNS:Offset in memory for the address decodingREMARKS:Return the offset given by mod=01 addressing. Also enables thedecoding of instructions.****************************************************************************/unsigned decode_rm01_address( int rm){ int displacement = (s8)fetch_byte_imm(); if (M.x86.mode & SYSMODE_PREFIX_ADDR) { switch (rm) { case 0: DECODE_PRINTF2("%d[EAX}", displacement); return M.x86.R_EAX + displacement; case 1: DECODE_PRINTF2("%d[ECX]", displacement); return M.x86.R_ECX + displacement; case 2: DECODE_PRINTF2("%d[EDX]", displacement); return M.x86.R_EDX + displacement; case 3: DECODE_PRINTF2("%d[EBX]", displacement); return M.x86.R_EBX + displacement; case 4: printk("Unsupported SIB addressing mode\n"); HALT_SYS(); return 0; case 5: DECODE_PRINTF2("%d[EBP]", displacement); return M.x86.R_EBP + displacement; case 6: DECODE_PRINTF2("%d[ESI]", displacement); return M.x86.R_ESI + displacement; case 7: DECODE_PRINTF2("%d[EDI]", displacement); return M.x86.R_EDI + displacement; } } else { switch (rm) { case 0: DECODE_PRINTF2("%d[BX+SI]", displacement); return M.x86.R_BX + M.x86.R_SI + displacement; case 1: DECODE_PRINTF2("%d[BX+DI]", displacement); return M.x86.R_BX + M.x86.R_DI + displacement; case 2: DECODE_PRINTF2("%d[BP+SI]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; return M.x86.R_BP + M.x86.R_SI + displacement; case 3: DECODE_PRINTF2("%d[BP+DI]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; return M.x86.R_BP + M.x86.R_DI + displacement; case 4: DECODE_PRINTF2("%d[SI]", displacement); return M.x86.R_SI + displacement; case 5: DECODE_PRINTF2("%d[DI]", displacement); return M.x86.R_DI + displacement; case 6: DECODE_PRINTF2("%d[BP]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; return M.x86.R_BP + displacement; case 7: DECODE_PRINTF2("%d[BX]", displacement); return M.x86.R_BX + displacement; } HALT_SYS(); } return 0; /* SHOULD NOT HAPPEN */}/****************************************************************************PARAMETERS:rm - RM value to decodeRETURNS:Offset in memory for the address decodingREMARKS:Return the offset given by mod=10 addressing. Also enables thedecoding of instructions.****************************************************************************/unsigned decode_rm10_address( int rm){ if (M.x86.mode & SYSMODE_PREFIX_ADDR) { int displacement = (s32)fetch_long_imm(); switch (rm) { case 0: DECODE_PRINTF2("%d[EAX}", displacement); return M.x86.R_EAX + displacement; case 1: DECODE_PRINTF2("%d[ECX]", displacement); return M.x86.R_ECX + displacement; case 2: DECODE_PRINTF2("%d[EDX]", displacement); return M.x86.R_EDX + displacement; case 3: DECODE_PRINTF2("%d[EBX]", displacement); return M.x86.R_EBX + displacement; case 4: printk("Unsupported SIB addressing mode\n"); HALT_SYS(); return 0; case 5: DECODE_PRINTF2("%d[EBP]", displacement); return M.x86.R_EBP + displacement; case 6: DECODE_PRINTF2("%d[ESI]", displacement); return M.x86.R_ESI + displacement; case 7: DECODE_PRINTF2("%d[EDI]", displacement); return M.x86.R_EDI + displacement; } } else { int displacement = (s16)fetch_word_imm(); switch (rm) { case 0: DECODE_PRINTF2("%d[BX+SI]", displacement); return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff; case 1: DECODE_PRINTF2("%d[BX+DI]", displacement); return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff; case 2: DECODE_PRINTF2("%d[BP+SI]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff; case 3: DECODE_PRINTF2("%d[BP+DI]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff; case 4: DECODE_PRINTF2("%d[SI]", displacement); return (M.x86.R_SI + displacement) & 0xffff; case 5: DECODE_PRINTF2("%d[DI]", displacement); return (M.x86.R_DI + displacement) & 0xffff; case 6: DECODE_PRINTF2("%d[BP]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; return (M.x86.R_BP + displacement) & 0xffff; case 7: DECODE_PRINTF2("%d[BX]", displacement); return (M.x86.R_BX + displacement) & 0xffff; } } HALT_SYS(); return 0; /*NOTREACHED */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -