/* * opcodes.h - opcodes for the 8086 processor * * Copyright (C) 1997-2003 Gero Kuhlmann * * 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 */