/*
* opcodes.h - opcodes for the 8086 processor
*
* Copyright (C) 1997-2003 Gero Kuhlmann <gero@gkminix.han.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: opcodes.h,v 1.4 2003/01/25 23:29:44 gkminix Exp $
*/
/*
* Definition of opcodes for 8086 processor
*/
#define OP_JMP_SHORT 0xeb /* short jump - one byte displacement */
#define OP_JMP_NEAR 0xe9 /* near jump - two byte displacement */
#define OP_JMP_COND 0x70 /* base of conditional jump */
#define OP_386 0x0f /* special operations on i386 */
#define OP_SET_COND 0x90 /* base of bit set operation */
#define OP_CALL 0xe8 /* near call - two byte displacement */
#define OP_RET 0xc3 /* return near */
#define OP_IMMED 0x80 /* base for immediate arithmetic */
#define OP_NONIM 0xf6 /* base for non-immediate arithmetic */
#define OP_REP 0xf2 /* repeat prefix */
#define OP_REPNE 0xf2 /* repeat while not equal */
#define OP_REPE 0xf3 /* repeat while equal */
#define OP_MOVSB 0xa4 /* move string bytewise */
#define OP_SCASB 0xae /* scan string bytewise */
#define OP_STOSB 0xaa /* store string bytewise */
#define OP_LODSB 0xac /* load a string bytewise */
#define OP_CMPSB 0xa6 /* compare two strings bytewise */
#define OP_MOV_AX 0xa0 /* move AX in/out of immediate memory */
#define OP_MOV_BREGIM 0xb0 /* move immediate value into byte reg */
#define OP_MOV_WREGIM 0xb8 /* move immediate value into word reg */
#define OP_MOV_MEMIM 0xc6 /* move immediate value into mem */
#define OP_PUSH_REG 0x50 /* push normal register */
#define OP_PUSH_MEM 0xff /* push memory */
#define OP_POP_REG 0x58 /* pop normal register */
#define OP_POP_MEM 0x8f /* pop memory */
#define OP_ADC 0x10 /* add with carry */
#define OP_ADD 0x00 /* add */
#define OP_AND 0x20 /* AND */
#define OP_CMP 0x38 /* compare */
#define OP_MOV 0x88 /* move */
#define OP_OR 0x08 /* OR */
#define OP_SBB 0x18 /* subtract with borrow */
#define OP_SUB 0x28 /* subtract */
#define OP_XOR 0x30 /* XOR */
#define OP_XCHG 0x86 /* exchange */
#define OP_LEA 0x8d /* load effective address */
#define OP_INC_REG16 0x40 /* increment 16 bit register */
#define OP_DEC_REG16 0x48 /* decrement 16 bit register */
#define OP_INC_MEM 0xfe /* increment 8 bit reg / mem */
#define OP_DEC_MEM 0xfe /* decrement 8 bit reg / mem */
#define OP_SHIFT_1 0xd0 /* shift by one bit */
#define OP_SHIFT_CL 0xd2 /* shift by CL bits */
#define OP_JCXZ 0xe3 /* jump if CX zero */
#define OP_LOOP 0xe2 /* decrement CX and jump if not zero */
#define OP_CBW 0x98 /* convert byte to word */
#define OP_CWD 0x99 /* convert word to double-word */
#define OP_BOUND 0x62 /* check array bounds */
#define OP_INT 0xcd /* call an interrupt */
#define OP_INTO 0xce /* call int 4 if overflow */
#define OP_ENTER 0xc8 /* enter a procedure */
#define OP_LEAVE 0xc9 /* leave a procedure */
#define OP_NOP 0x90 /* no operation */
#define OP_CLD 0xfc /* clear direction flag */
/*
* Arithmetic instructions with immediate values have a base opcode, and
* the type of instruction is encoded in the reg field of the mod-r/m byte.
* The same is true for some non-immediate opcodes, and shift/rotate in-
* structions.
*/
#define OP_IMMED_MASK 0x38 /* mask for opcode */
#define OP_IMMED_ADC 0x10 /* immediate addition with carry */
#define OP_IMMED_ADD 0x00 /* immediate addition */
#define OP_IMMED_AND 0x20 /* immediate AND */
#define OP_IMMED_CMP 0x38 /* immediate comparison */
#define OP_IMMED_OR 0x08 /* immediate OR */
#define OP_IMMED_SBB 0x18 /* immediate subtract with borrow */
#define OP_IMMED_SUB 0x28 /* immediate subtraction */
#define OP_IMMED_XOR 0x30 /* immediate XOR */
#define OP_NONIM_MASK 0x38 /* mask for opcode */
#define OP_NONIM_DIV 0x30 /* unsigned division */
#define OP_NONIM_IDIV 0x38 /* signed division */
#define OP_NONIM_IMUL 0x28 /* signed multiplication */
#define OP_NONIM_MUL 0x20 /* unsigned multiplication */
#define OP_NONIM_NEG 0x18 /* two's complement negation */
#define OP_NONIM_NOT 0x10 /* one's complement negation */
#define OP_SHIFT_MASK 0x38 /* mask for opcode */
#define OP_SHIFT_ROL 0x00 /* rotate left */
#define OP_SHIFT_ROR 0x08 /* rotate right */
#define OP_SHIFT_RCL 0x10 /* rotate left through carry */
#define OP_SHIFT_RCR 0x18 /* rotate right through carry */
#define OP_SHIFT_SHL 0x20 /* shift left (for SHL and SAL) */
#define OP_SHIFT_SHR 0x28 /* shift right */
#define OP_SHIFT_SAR 0x38 /* shift arithmetic right */
#define OP_MEM_MASK 0x38 /* mask for opcode */
#define OP_MEM_PUSH 0x30 /* push memory location */
#define OP_MEM_CALL16 0x10 /* call near indirect */
#define OP_MEM_CALL32 0x18 /* call far indirect */
#define OP_MEM_DEC 0x08 /* decrement */
#define OP_MEM_INC 0x00 /* increment */
#define OP_MEM_JMP16 0x20 /* jmp near indirect */
#define OP_MEM_JMP32 0x28 /* jmp far indirect */
/*
* Jump conditions. These reflect the lower 4 bits of the conditional jump
* opcode except for the unconditional jump.
*/
#define JMP_UNCOND 0xff
#define JMP_JO 0x00 /* overflow */
#define JMP_JNO 0x01 /* not overflow */
#define JMP_JC 0x02 /* carry */
#define JMP_JNC 0x03 /* not carry */
#define JMP_JZ 0x04 /* zero */
#define JMP_JNZ 0x05 /* not zero */
#define JMP_JBE 0x06 /* below or equal */
#define JMP_JA 0x07 /* above */
#define JMP_JS 0x08 /* sign */
#define JMP_JNS 0x09 /* not sign */
#define JMP_JP 0x0a /* parity */
#define JMP_JNP 0x0b /* not parity */
#define JMP_JL 0x0c /* lower */
#define JMP_JGE 0x0d /* greater or equal */
#define JMP_JLE 0x0e /* lower or equal */
#define JMP_JG 0x0f /* greater */
/*
* Register names. The values in the lower byte are the same as used
* by the processor for the corresponding register. Sometimes the
* register value is in the lower 3 bits of the mod-r/m field, and
* sometimes it is in the middle 3 bits. The two macros rmlow and
* rmmid adjust the register value accordingly.
*/
#define rmlow(a) (((a) & REG_16BIT_MASK) >> 3)
#define rmmid(a) ((a) & REG_16BIT_MASK)
#define regcmp(a,b) ((a) == (b) || \
(a) == ((b) + REG_LOW_MASK + REG_8BIT_FLAG) || \
(a) == ((b) + REG_HIGH_MASK + REG_8BIT_FLAG))
#define REG_NONE 0xffff /* no register specification */
#define REG_16BIT_MASK 0x0038 /* mask for 16 bit registers */
#define REG_8BIT_MASK 0x0018 /* mask for 8 bit registers */
#define REG_LOW_MASK 0x0000 /* mask for lower 8 bit register */
#define REG_HIGH_MASK 0x0020 /* mask for higher 8 bit register */
#define REG_8BIT_FLAG 0x0100 /* flag for 8 bit register */
#define REG_SEG_FLAG 0x0200 /* flag for segment register flag */
#define REG_SPEC_FLAG 0x0400 /* flag for special register flag */
#define REG_MODRM_FLAG 0x0800 /* flag for mod-r/m flag */
#define REG_RELOC_FLAG 0x1000 /* flag for reclocatable displacement */
#define REG_AX 0x0000
#define REG_AL (REG_AX + REG_LOW_MASK + REG_8BIT_FLAG)
#define REG_AH (REG_AX + REG_HIGH_MASK + REG_8BIT_FLAG)
#define REG_BX 0x0018
#define REG_BL (REG_BX + REG_LOW_MASK + REG_8BIT_FLAG)
#define REG_BH (REG_BX + REG_HIGH_MASK + REG_8BIT_FLAG)
#define REG_CX 0x0008
#define REG_CL (REG_CX + REG_LOW_MASK + REG_8BIT_FLAG)
#define REG_CH (REG_CX + REG_HIGH_MASK + REG_8BIT_FLAG)
#define REG_DX 0x0010
#define REG_DL (REG_DX + REG_LOW_MASK + REG_8BIT_FLAG)
#define REG_DH (REG_DX + REG_HIGH_MASK + REG_8BIT_FLAG)
#define REG_ES (0x0000 + REG_SEG_FLAG)
#define REG_CS (0x0008 + REG_SEG_FLAG)
#define REG_SS (0x0010 + REG_SEG_FLAG)
#define REG_DS (0x0018 + REG_SEG_FLAG)
#define REG_SP (0x0020 + REG_SPEC_FLAG)
#define REG_BP (0x0028 + REG_SPEC_FLAG)
#define REG_SI (0x0030 + REG_SPEC_FLAG)
#define REG_DI (0x0038 + REG_SPEC_FLAG)
#define REG_SI_16DISP (REG_MODRM_FLAG + OP_MOD_16BIT + OP_RM_IND + OP_RM_SI)
#define REG_SI_8DISP (REG_MODRM_FLAG + OP_MOD_8BIT + OP_RM_IND + OP_RM_SI)
#define REG_SI_0DISP (REG_MODRM_FLAG + OP_MOD_DIRECT + OP_RM_IND + OP_RM_SI)
#define REG_DI_16DISP (REG_MODRM_FLAG + OP_MOD_16BIT + OP_RM_IND + OP_RM_DI)
#define REG_DI_8DISP (REG_MODRM_FLAG + OP_MOD_8BIT + OP_RM_IND + OP_RM_DI)
#define REG_DI_0DISP (REG_MODRM_FLAG + OP_MOD_DIRECT + OP_RM_IND + OP_RM_DI)
#define REG_BX_16DISP (REG_MODRM_FLAG + OP_MOD_16BIT + OP_RM_BX)
#define REG_BX_8DISP (REG_MODRM_FLAG + OP_MOD_8BIT + OP_RM_BX)
#define REG_BX_0DISP (REG_MODRM_FLAG + OP_MOD_DIRECT + OP_RM_BX)
#define REG_BP_16DISP (REG_MODRM_FLAG + OP_MOD_16BIT + OP_RM_BP)
#define REG_BP_8DISP (REG_MODRM_FLAG + OP_MOD_8BIT + OP_RM_BP)
#define REG_16DISP (REG_MODRM_FLAG + OP_MOD_DIRECT + OP_RM_BP)
/*
* Define various masks for constructing the mod-r/m byte and set
* the direction and word size flags.
*/
#define OP_SIGN_MASK 0x02 /* Sign bit in opcode */
#define OP_DIR_MASK 0x02 /* Direction bit in opcode */
#define OP_WORD_MASK 0x01 /* Operand size bit in opcode */
#define OP_MOD_MASK 0xc0 /* mask for mod field */
#define OP_MOD_DIRECT 0x00 /* use direct displacement */
#define OP_MOD_8BIT 0x40 /* 8 bit displacement */
#define OP_MOD_16BIT 0x80 /* 16 bit displacement */
#define OP_MOD_REG 0xc0 /* register to register operation */
#define OP_RM_MASK 0x07 /* Mask for r/m field */
#define OP_RM_SI 0x00 /* Use SI register for effective addr */
#define OP_RM_DI 0x01 /* Use DI register for effective addr */
#define OP_RM_BXIND 0x00 /* Use BX+indexreg+disp */
#define OP_RM_BPIND 0x02 /* Use BP+indexref+disp */
#define OP_RM_IND 0x04 /* Use indexreg+disp */
#define OP_RM_BP 0x06 /* Use BP+disp or disp without reg */
#define OP_RM_BX 0x07 /* Use BX+disp */
syntax highlighted by Code2HTML, v. 0.9.1