decode.c
来自「适合KS8695X」· C语言 代码 · 共 971 行 · 第 1/2 页
C
971 行
{
#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 at
offset - Offset to store data at
val - Value to store
REMARKS:
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 at
offset - Offset to store data at
val - Value to store
REMARKS:
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 decode
RETURNS:
Pointer to the appropriate register
REMARKS:
Return a pointer to the register given by the R/RM field of the
modrm 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 decode
RETURNS:
Pointer to the appropriate register
REMARKS:
Return a pointer to the register given by the R/RM field of the
modrm 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 decode
RETURNS:
Pointer to the appropriate register
REMARKS:
Return a pointer to the register given by the R/RM field of the
modrm 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 decode
RETURNS:
Pointer to the appropriate register
REMARKS:
Return a pointer to the register given by the R/RM field of the
modrm byte, for word operands, modified from above for the weirdo
special 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 decode
RETURNS:
Offset in memory for the address decoding
REMARKS:
Return the offset given by mod=00 addressing. Also enables the
decoding 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 decode
RETURNS:
Offset in memory for the address decoding
REMARKS:
Return the offset given by mod=01 addressing. Also enables the
decoding 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 decode
RETURNS:
Offset in memory for the address decoding
REMARKS:
Return the offset given by mod=10 addressing. Also enables the
decoding 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 + =
减小字号Ctrl + -
显示快捷键?