📄 nasm.h
字号:
};
/*
* -----------------------------------------------------------
* Format of the `insn' structure returned from `parser.c' and
* passed into `assemble.c'
* -----------------------------------------------------------
*/
/*
* Here we define the operand types. These are implemented as bit
* masks, since some are subsets of others; e.g. AX in a MOV
* instruction is a special operand type, whereas AX in other
* contexts is just another 16-bit register. (Also, consider CL in
* shift instructions, DX in OUT, etc.)
*
* The basic concept here is that
* (class & ~operand) == 0
*
* if and only if "operand" belongs to class type "class".
*
* The bits are assigned as follows:
*
* Bits 0-7, 29: sizes
* 0: 8 bits (BYTE)
* 1: 16 bits (WORD)
* 2: 32 bits (DWORD)
* 3: 64 bits (QWORD)
* 4: 80 bits (TWORD)
* 5: FAR
* 6: NEAR
* 7: SHORT
* 29: 128 bits (OWORD)
*
* Bits 8-11 modifiers
* 8: TO
* 9: COLON
* 10: STRICT
* 11: (reserved)
*
* Bits 12-15: type of operand
* 12: REGISTER
* 13: IMMEDIATE
* 14: MEMORY (always has REGMEM attribute as well)
* 15: REGMEM (valid EA operand)
*
* Bits 16-19: subclasses
* With REG_CDT:
* 16: REG_CREG (CRx)
* 17: REG_DREG (DRx)
* 18: REG_TREG (TRx)
* With REG_GPR:
* 16: REG_ACCUM (AL, AX, EAX, RAX)
* 17: REG_COUNT (CL, CX, ECX, RCX)
* 18: REG_DATA (DL, DX, EDX, RDX)
* 19: REG_HIGH (AH, CH, DH, BH)
*
* With REG_SREG:
* 16: REG_CS
* 17: REG_DESS (DS, ES, SS)
* 18: REG_FSGS
* 19: REG_SEG67
*
* With FPUREG:
* 16: FPU0
*
* With XMMREG:
* 16: XMM0
*
* With MEMORY:
* 16: MEM_OFFS (this is a simple offset)
* 17: IP_REL (IP-relative offset)
*
* With IMMEDIATE:
* 16: UNITY (1)
* 17: BYTENESS (-128..127)
*
* Bits 20-26: register classes
* 20: REG_CDT (CRx, DRx, TRx)
* 21: RM_GPR (REG_GPR) (integer register)
* 22: REG_SREG
* 23: IP_REG (RIP or EIP) [unused]
* 24: FPUREG
* 25: RM_MMX (MMXREG)
* 26: RM_XMM (XMMREG)
*
* Bits 27-29 & 31 are currently unallocated.
*
* 30: SAME_AS
* Special flag only used in instruction patterns; means this operand
* has to be identical to another operand. Currently only supported
* for registers.
*/
typedef uint32_t opflags_t;
/* Size, and other attributes, of the operand */
#define BITS8 0x00000001L
#define BITS16 0x00000002L
#define BITS32 0x00000004L
#define BITS64 0x00000008L /* x64 and FPU only */
#define BITS80 0x00000010L /* FPU only */
#define BITS128 0x20000000L
#define FAR 0x00000020L /* grotty: this means 16:16 or */
/* 16:32, like in CALL/JMP */
#define NEAR 0x00000040L
#define SHORT 0x00000080L /* and this means what it says :) */
#define SIZE_MASK 0x200000FFL /* all the size attributes */
/* Modifiers */
#define MODIFIER_MASK 0x00000f00L
#define TO 0x00000100L /* reverse effect in FADD, FSUB &c */
#define COLON 0x00000200L /* operand is followed by a colon */
#define STRICT 0x00000400L /* do not optimize this operand */
/* Type of operand: memory reference, register, etc. */
#define OPTYPE_MASK 0x0000f000L
#define REGISTER 0x00001000L /* register number in 'basereg' */
#define IMMEDIATE 0x00002000L
#define MEMORY 0x0000c000L
#define REGMEM 0x00008000L /* for r/m, ie EA, operands */
/* Register classes */
#define REG_EA 0x00009000L /* 'normal' reg, qualifies as EA */
#define RM_GPR 0x00208000L /* integer operand */
#define REG_GPR 0x00209000L /* integer register */
#define REG8 0x00209001L /* 8-bit GPR */
#define REG16 0x00209002L /* 16-bit GPR */
#define REG32 0x00209004L /* 32-bit GPR */
#define REG64 0x00209008L /* 64-bit GPR */
#define IP_REG 0x00801000L /* RIP or EIP register */
#define RIPREG 0x00801008L /* RIP */
#define EIPREG 0x00801004L /* EIP */
#define FPUREG 0x01001000L /* floating point stack registers */
#define FPU0 0x01011000L /* FPU stack register zero */
#define RM_MMX 0x02008000L /* MMX operand */
#define MMXREG 0x02009000L /* MMX register */
#define RM_XMM 0x04008000L /* XMM (SSE) operand */
#define XMMREG 0x04009000L /* XMM (SSE) register */
#define XMM0 0x04019000L /* XMM register zero */
#define REG_CDT 0x00101004L /* CRn, DRn and TRn */
#define REG_CREG 0x00111004L /* CRn */
#define REG_DREG 0x00121004L /* DRn */
#define REG_TREG 0x00141004L /* TRn */
#define REG_SREG 0x00401002L /* any segment register */
#define REG_CS 0x00411002L /* CS */
#define REG_DESS 0x00421002L /* DS, ES, SS */
#define REG_FSGS 0x00441002L /* FS, GS */
#define REG_SEG67 0x00481002L /* Unimplemented segment registers */
#define REG_RIP 0x00801008L /* RIP relative addressing */
#define REG_EIP 0x00801004L /* EIP relative addressing */
/* Special GPRs */
#define REG_SMASK 0x000f0000L /* a mask for the following */
#define REG_ACCUM 0x00219000L /* accumulator: AL, AX, EAX, RAX */
#define REG_AL 0x00219001L
#define REG_AX 0x00219002L
#define REG_EAX 0x00219004L
#define REG_RAX 0x00219008L
#define REG_COUNT 0x00229000L /* counter: CL, CX, ECX, RCX */
#define REG_CL 0x00229001L
#define REG_CX 0x00229002L
#define REG_ECX 0x00229004L
#define REG_RCX 0x00229008L
#define REG_DL 0x00249001L /* data: DL, DX, EDX, RDX */
#define REG_DX 0x00249002L
#define REG_EDX 0x00249004L
#define REG_RDX 0x00249008L
#define REG_HIGH 0x00289001L /* high regs: AH, CH, DH, BH */
/* special types of EAs */
#define MEM_OFFS 0x0001c000L /* simple [address] offset - absolute! */
#define IP_REL 0x0002c000L /* IP-relative offset */
/* memory which matches any type of r/m operand */
#define MEMORY_ANY (MEMORY|RM_GPR|RM_MMX|RM_XMM)
/* special type of immediate operand */
#define UNITY 0x00012000L /* for shift/rotate instructions */
#define SBYTE 0x00022000L /* for op r16/32,immediate instrs. */
/* special flags */
#define SAME_AS 0x40000000L
/* Register names automatically generated from regs.dat */
#include "regs.h"
enum ccode { /* condition code names */
C_A, C_AE, C_B, C_BE, C_C, C_E, C_G, C_GE, C_L, C_LE, C_NA, C_NAE,
C_NB, C_NBE, C_NC, C_NE, C_NG, C_NGE, C_NL, C_NLE, C_NO, C_NP,
C_NS, C_NZ, C_O, C_P, C_PE, C_PO, C_S, C_Z,
C_none = -1
};
/*
* REX flags
*/
#define REX_OC 0x0200 /* DREX suffix has the OC0 bit set */
#define REX_D 0x0100 /* Instruction uses DREX instead of REX */
#define REX_H 0x80 /* High register present, REX forbidden */
#define REX_P 0x40 /* REX prefix present/required */
#define REX_L 0x20 /* Use LOCK prefix instead of REX.R */
#define REX_W 0x08 /* 64-bit operand size */
#define REX_R 0x04 /* ModRM reg extension */
#define REX_X 0x02 /* SIB index extension */
#define REX_B 0x01 /* ModRM r/m extension */
#define REX_REAL 0x4f /* Actual REX prefix bits */
/*
* Note that because segment registers may be used as instruction
* prefixes, we must ensure the enumerations for prefixes and
* register names do not overlap.
*/
enum prefixes { /* instruction prefixes */
PREFIX_ENUM_START = REG_ENUM_LIMIT,
P_A16 = PREFIX_ENUM_START, P_A32, P_LOCK, P_O16, P_O32,
P_REP, P_REPE, P_REPNE, P_REPNZ, P_REPZ, P_TIMES
};
enum { /* extended operand types */
EOT_NOTHING, EOT_DB_STRING, EOT_DB_NUMBER
};
enum { /* special EA flags */
EAF_BYTEOFFS = 1, /* force offset part to byte size */
EAF_WORDOFFS = 2, /* force offset part to [d]word size */
EAF_TIMESTWO = 4, /* really do EAX*2 not EAX+EAX */
EAF_REL = 8, /* IP-relative addressing */
EAF_ABS = 16, /* non-IP-relative addressing */
EAF_FSGS = 32 /* fs/gs segment override present */
};
enum eval_hint { /* values for `hinttype' */
EAH_NOHINT = 0, /* no hint at all - our discretion */
EAH_MAKEBASE = 1, /* try to make given reg the base */
EAH_NOTBASE = 2 /* try _not_ to make reg the base */
};
typedef struct { /* operand to an instruction */
int32_t type; /* type of operand */
int addr_size; /* 0 means default; 16; 32; 64 */
enum reg_enum basereg, indexreg; /* address registers */
int scale; /* index scale */
int hintbase;
enum eval_hint hinttype; /* hint as to real base register */
int32_t segment; /* immediate segment, if needed */
int64_t offset; /* any immediate number */
int32_t wrt; /* segment base it's relative to */
int eaflags; /* special EA flags */
int opflags; /* see OPFLAG_* defines below */
} operand;
#define OPFLAG_FORWARD 1 /* operand is a forward reference */
#define OPFLAG_EXTERN 2 /* operand is an external reference */
typedef struct extop { /* extended operand */
struct extop *next; /* linked list */
int32_t type; /* defined above */
char *stringval; /* if it's a string, then here it is */
int stringlen; /* ... and here's how long it is */
int32_t segment; /* if it's a number/address, then... */
int64_t offset; /* ... it's given here ... */
int32_t wrt; /* ... and here */
} extop;
#define MAXPREFIX 4
#define MAX_OPERANDS 4
typedef struct { /* an instruction itself */
char *label; /* the label defined, or NULL */
enum prefixes prefixes[MAXPREFIX]; /* instruction prefixes, if any */
int nprefix; /* number of entries in above */
enum opcode opcode; /* the opcode - not just the string */
enum ccode condition; /* the condition code, if Jcc/SETcc */
int operands; /* how many operands? 0-3
* (more if db et al) */
operand oprs[MAX_OPERANDS]; /* the operands, defined as above */
extop *eops; /* extended operands */
int eops_float; /* true if DD and floating */
int32_t times; /* repeat count (TIMES prefix) */
int forw_ref; /* is there a forward reference? */
int rex; /* Special REX Prefix */
int drexdst; /* Destination register for DREX suffix */
} insn;
enum geninfo { GI_SWITCH };
/*
* ------------------------------------------------------------
* The data structure defining an output format driver, and the
* interfaces to the functions therein.
* ------------------------------------------------------------
*/
struct ofmt {
/*
* This is a short (one-liner) description of the type of
* output generated by the driver.
*/
const char *fullname;
/*
* This is a single keyword used to select the driver.
*/
const char *shortname;
/*
* this is reserved for out module specific help.
* It is set to NULL in all the out modules and is not implemented
* in the main program
*/
const char *helpstring;
/*
* this is a pointer to the first element of the debug information
*/
struct dfmt **debug_formats;
/*
* and a pointer to the element that is being used
* note: this is set to the default at compile time and changed if the
* -F option is selected. If developing a set of new debug formats for
* an output format, be sure to set this to whatever default you want
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -