⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nasm.h

📁 汇编编译器的最新版本的源码.买了自己动手写操作系统这本书的人一定要下
💻 H
📖 第 1 页 / 共 3 页
字号:
 */

/*
 * isidstart matches any character that may start an identifier, and isidchar
 * matches any character that may appear at places other than the start of an
 * identifier. E.g. a period may only appear at the start of an identifier
 * (for local labels), whereas a number may appear anywhere *but* at the
 * start.
 */

#define isidstart(c) ( nasm_isalpha(c) || (c)=='_' || (c)=='.' || (c)=='?' \
                                  || (c)=='@' )
#define isidchar(c)  ( isidstart(c) || nasm_isdigit(c) || \
		       (c)=='$' || (c)=='#' || (c)=='~' )

/* Ditto for numeric constants. */

#define isnumstart(c)  ( nasm_isdigit(c) || (c)=='$' )
#define isnumchar(c)   ( nasm_isalnum(c) || (c)=='_' )

/* This returns the numeric value of a given 'digit'. */

#define numvalue(c)  ((c)>='a' ? (c)-'a'+10 : (c)>='A' ? (c)-'A'+10 : (c)-'0')

/*
 * Data-type flags that get passed to listing-file routines.
 */
enum {
    LIST_READ, LIST_MACRO, LIST_MACRO_NOLIST, LIST_INCLUDE,
    LIST_INCBIN, LIST_TIMES
};

/*
 * -----------------------------------------------------------
 * 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, 23, 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
 * 23: 256 bits (YWORD)
 * 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, 28: 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)
 * 28: REG_NOTACC (not REG_ACCUM)
 *
 * 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 YMMREG:
 * 16: YMM0
 *
 * With MEMORY:
 * 16: MEM_OFFS (this is a simple offset)
 * 17: IP_REL (IP-relative offset)
 *
 * With IMMEDIATE:
 * 16: UNITY (1)
 * 17: BYTENESS16 (-128..127)
 * 18: BYTENESS32 (-128..127)
 * 19: BYTENESS64 (-128..127)
 *
 * Bits 20-22, 24-27: register classes
 * 20: REG_CDT (CRx, DRx, TRx)
 * 21: RM_GPR (REG_GPR) (integer register)
 * 22: REG_SREG
 * 24: FPUREG
 * 25: RM_MMX (MMXREG)
 * 26: RM_XMM (XMMREG)
 * 27: RM_YMM (YMMREG)
 *
 * Bit 31 is 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		0x00000001U
#define BITS16		0x00000002U
#define BITS32		0x00000004U
#define BITS64		0x00000008U   /* x64 and FPU only */
#define BITS80		0x00000010U   /* FPU only */
#define BITS128		0x20000000U
#define BITS256		0x00800000U
#define FAR		0x00000020U   /* grotty: this means 16:16 or */
                                       /* 16:32, like in CALL/JMP */
#define NEAR		0x00000040U
#define SHORT		0x00000080U   /* and this means what it says :) */

#define SIZE_MASK	0x208000FFU   /* all the size attributes */

/* Modifiers */
#define MODIFIER_MASK	0x00000f00U
#define TO		0x00000100U   /* reverse effect in FADD, FSUB &c */
#define COLON		0x00000200U   /* operand is followed by a colon */
#define STRICT		0x00000400U   /* do not optimize this operand */

/* Type of operand: memory reference, register, etc. */
#define OPTYPE_MASK	0x0000f000U
#define REGISTER	0x00001000U   /* register number in 'basereg' */
#define IMMEDIATE	0x00002000U
#define MEMORY		0x0000c000U
#define REGMEM		0x00008000U   /* for r/m, ie EA, operands */

/* Register classes */
#define REG_EA		0x00009000U   /* 'normal' reg, qualifies as EA */
#define RM_GPR		0x00208000U   /* integer operand */
#define REG_GPR		0x00209000U   /* integer register */
#define REG8		0x00209001U   /*  8-bit GPR  */
#define REG16		0x00209002U   /* 16-bit GPR */
#define REG32		0x00209004U   /* 32-bit GPR */
#define REG64		0x00209008U   /* 64-bit GPR */
#define FPUREG		0x01001000U   /* floating point stack registers */
#define FPU0		0x01011000U   /* FPU stack register zero */
#define RM_MMX		0x02008000U   /* MMX operand */
#define MMXREG		0x02009000U   /* MMX register */
#define RM_XMM		0x04008000U   /* XMM (SSE) operand */
#define XMMREG		0x04009000U   /* XMM (SSE) register */
#define XMM0		0x04019000U   /* XMM register zero */
#define RM_YMM		0x08008000U   /* YMM (AVX) operand */
#define YMMREG		0x08009000U   /* YMM (AVX) register */
#define YMM0		0x08019000U   /* YMM register zero */
#define REG_CDT		0x00101004U   /* CRn, DRn and TRn */
#define REG_CREG	0x00111004U   /* CRn */
#define REG_DREG	0x00121004U   /* DRn */
#define REG_TREG	0x00141004U   /* TRn */
#define REG_SREG	0x00401002U   /* any segment register */
#define REG_CS		0x00411002U   /* CS */
#define REG_DESS	0x00421002U   /* DS, ES, SS */
#define REG_FSGS	0x00441002U   /* FS, GS */
#define REG_SEG67	0x00481002U   /* Unimplemented segment registers */

#define REG_RIP		0x00801008U   /* RIP relative addressing */
#define REG_EIP		0x00801004U   /* EIP relative addressing */

/* Special GPRs */
#define REG_SMASK	0x100f0000U   /* a mask for the following */
#define REG_ACCUM	0x00219000U   /* accumulator: AL, AX, EAX, RAX */
#define REG_AL		0x00219001U
#define REG_AX		0x00219002U
#define REG_EAX		0x00219004U
#define REG_RAX		0x00219008U
#define REG_COUNT	0x10229000U   /* counter: CL, CX, ECX, RCX */
#define REG_CL		0x10229001U
#define REG_CX		0x10229002U
#define REG_ECX		0x10229004U
#define REG_RCX		0x10229008U
#define REG_DL		0x10249001U   /* data: DL, DX, EDX, RDX */
#define REG_DX		0x10249002U
#define REG_EDX		0x10249004U
#define REG_RDX		0x10249008U
#define REG_HIGH	0x10289001U   /* high regs: AH, CH, DH, BH */
#define REG_NOTACC	0x10000000U   /* non-accumulator register */
#define REG8NA		0x10209001U   /*  8-bit non-acc GPR  */
#define REG16NA		0x10209002U   /* 16-bit non-acc GPR */
#define REG32NA		0x10209004U   /* 32-bit non-acc GPR */
#define REG64NA		0x10209008U   /* 64-bit non-acc GPR */

/* special types of EAs */
#define MEM_OFFS	0x0001c000U   /* simple [address] offset - absolute! */
#define IP_REL		0x0002c000U   /* IP-relative offset */

/* memory which matches any type of r/m operand */
#define MEMORY_ANY	(MEMORY|RM_GPR|RM_MMX|RM_XMM|RM_YMM)

/* special type of immediate operand */
#define UNITY		0x00012000U   /* for shift/rotate instructions */
#define SBYTE16		0x00022000U   /* for op r16,immediate instrs. */
#define SBYTE32		0x00042000U   /* for op r32,immediate instrs. */
#define SBYTE64		0x00082000U   /* for op r64,immediate instrs. */
#define BYTENESS	0x000e0000U   /* for testing for byteness */

/* special flags */
#define SAME_AS		0x40000000U

/* 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_REAL	0x4f	/* Actual REX prefix bits */
#define REX_B		0x01	/* ModRM r/m extension */
#define REX_X		0x02	/* SIB index extension */
#define REX_R		0x04	/* ModRM reg extension */
#define REX_W		0x08	/* 64-bit operand size */
#define REX_L		0x20	/* Use LOCK prefix instead of REX.R */
#define REX_P		0x40	/* REX prefix present/required */
#define REX_H		0x80	/* High register present, REX forbidden */
#define REX_D		0x0100	/* Instruction uses DREX instead of REX */
#define REX_OC		0x0200	/* DREX suffix has the OC0 bit set */
#define REX_V		0x0400	/* Instruction uses VEX instead of REX */

/*
 * 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 */
    P_none = 0,
    PREFIX_ENUM_START = REG_ENUM_LIMIT,
    P_A16 = PREFIX_ENUM_START, P_A32, P_A64, P_ASP,
    P_LOCK, P_O16, P_O32, P_O64, P_OSP,
    P_REP, P_REPE, P_REPNE, P_REPNZ, P_REPZ, P_TIMES,
    PREFIX_ENUM_LIMIT
};

enum extop_type {		/* extended operand types */
    EOT_NOTHING,
    EOT_DB_STRING,		/* Byte string */
    EOT_DB_STRING_FREE,		/* Byte string which should be nasm_free'd*/
    EOT_DB_NUMBER,		/* Integer */
};

enum ea_flags {			/* 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 {	/* operand to an instruction */
    int32_t type;               /* type of operand */
    int disp_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 */
    char *stringval;	        /* if it's a string, then here it is */
    size_t stringlen;           /* ... and here's how long it is */
    int64_t offset;             /* ... it's given here ... */
    int32_t segment;            /* if it's a number/address, then... */
    int32_t wrt;                /* ... and here */
    enum extop_type type;	/* defined above */
} extop;

/* Prefix positions: each type of prefix goes in a specific slot.
   This affects the final ordering of the assembled output, which
   shouldn't matter to the processor, but if you have stylistic
   preferences, you can change this.  REX prefixes are handled
   differently for the time being.

   Note that LOCK and REP are in the same slot.  This is
   an x86 architectural constraint. */
enum prefix_pos {
    PPS_LREP,			/* Lock or REP prefix */
    PPS_SEG,			/* Segment override prefix */
    PPS_OSIZE,			/* Operand size prefix */
    PPS_ASIZE,			/* Address size prefix */
    MAXPREFIX			/* Total number of prefix slots */
};

/* If you need to change this, also change it in insns.pl */
#define MAX_OPERANDS 5

typedef struct insn {		/* an instruction itself */
    char *label;		/* the label defined, or NULL */
    enum prefixes prefixes[MAXPREFIX]; /* instruction prefixes, if any */
    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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -