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 + -
显示快捷键?