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

📄 nasm.h

📁 开源的nasm编译器源码,研究编译器原理很有帮且
💻 H
📖 第 1 页 / 共 2 页
字号:
/* special type of immediate operand */#define ONENESS   0x00800000L          /* so UNITY == IMMEDIATE | ONENESS */#define UNITY     0x00802000L	       /* for shift/rotate instructions */#define BYTENESS  0x40000000L          /* so SBYTE == IMMEDIATE | BYTENESS */#define SBYTE 	  0x40002000L	       /* for op r16/32,immediate instrs. */		/* Register names automatically generated from regs.dat */#include "regs.h"enum {				       /* 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};/* * 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 {				       /* 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 */};enum {				       /* 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 */    long type;			       /* type of operand */    int addr_size;		       /* 0 means default; 16; 32 */    int basereg, indexreg, scale;      /* registers and scale involved */    int hintbase, hinttype;	       /* hint as to real base register */    long segment;		       /* immediate segment, if needed */    long offset;		       /* any immediate number */    long 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 */    long type;			       /* defined above */    char *stringval;		       /* if it's a string, then here it is */    int stringlen;		       /* ... and here's how long it is */    long segment;		       /* if it's a number/address, then... */    long offset;		       /* ... it's given here ... */    long wrt;			       /* ... and here */} extop;#define MAXPREFIX 4typedef struct {		       /* an instruction itself */    char *label;		       /* the label defined, or NULL */    int prefixes[MAXPREFIX];	       /* instruction prefixes, if any */    int nprefix;		       /* number of entries in above */    int opcode;			       /* the opcode - not just the string */    int condition;		       /* the condition code, if Jcc/SETcc */    int operands;		       /* how many operands? 0-3                                         * (more if db et al) */    operand oprs[3];	   	       /* the operands, defined as above */    extop *eops;		       /* extended operands */    int eops_float;                    /* true if DD and floating */    long times;			       /* repeat count (TIMES prefix) */    int forw_ref;		       /* is there a forward reference? */} 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 but 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     *     */    struct dfmt *current_dfmt;    /*     * This, if non-NULL, is a NULL-terminated list of `char *'s     * pointing to extra standard macros supplied by the object     * format (e.g. a sensible initial default value of __SECT__,     * and user-level equivalents for any format-specific     * directives).     */    const char **stdmac;    /*     * This procedure is called at the start of an output session.     * It tells the output format what file it will be writing to,     * what routine to report errors through, and how to interface     * to the label manager and expression evaluator if necessary.     * It also gives it a chance to do other initialisation.     */    void (*init) (FILE *fp, efunc error, ldfunc ldef, evalfunc eval);    /*     * This procedure is called to pass generic information to the     * object file.  The first parameter gives the information type     * (currently only command line switches)     * and the second parameter gives the value.  This function returns     * 1 if recognized, 0 if unrecognized     */    int (*setinfo)(enum geninfo type, char **string);    /*     * This procedure is called by assemble() to write actual     * generated code or data to the object file. Typically it     * doesn't have to actually _write_ it, just store it for     * later.     *     * The `type' argument specifies the type of output data, and     * usually the size as well: its contents are described below.     */    void (*output) (long segto, const void *data, unsigned long type,		    long segment, long wrt);    /*     * This procedure is called once for every symbol defined in     * the module being assembled. It gives the name and value of     * the symbol, in NASM's terms, and indicates whether it has     * been declared to be global. Note that the parameter "name",     * when passed, will point to a piece of static storage     * allocated inside the label manager - it's safe to keep using     * that pointer, because the label manager doesn't clean up     * until after the output driver has.     *     * Values of `is_global' are: 0 means the symbol is local; 1     * means the symbol is global; 2 means the symbol is common (in     * which case `offset' holds the _size_ of the variable).     * Anything else is available for the output driver to use     * internally.     *     * This routine explicitly _is_ allowed to call the label     * manager to define further symbols, if it wants to, even     * though it's been called _from_ the label manager. That much     * re-entrancy is guaranteed in the label manager. However, the     * label manager will in turn call this routine, so it should     * be prepared to be re-entrant itself.     *     * The `special' parameter contains special information passed     * through from the command that defined the label: it may have     * been an EXTERN, a COMMON or a GLOBAL. The distinction should     * be obvious to the output format from the other parameters.     */    void (*symdef) (char *name, long segment, long offset, int is_global,		    char *special);    /*     * This procedure is called when the source code requests a     * segment change. It should return the corresponding segment     * _number_ for the name, or NO_SEG if the name is not a valid     * segment name.     *     * It may also be called with NULL, in which case it is to     * return the _default_ section number for starting assembly in.     *     * It is allowed to modify the string it is given a pointer to.     *     * It is also allowed to specify a default instruction size for     * the segment, by setting `*bits' to 16 or 32. Or, if it     * doesn't wish to define a default, it can leave `bits' alone.     */    long (*section) (char *name, int pass, int *bits);    /*     * This procedure is called to modify the segment base values     * returned from the SEG operator. It is given a segment base     * value (i.e. a segment value with the low bit set), and is     * required to produce in return a segment value which may be     * different. It can map segment bases to absolute numbers by     * means of returning SEG_ABS types.     *     * It should return NO_SEG if the segment base cannot be     * determined; the evaluator (which calls this routine) is     * responsible for throwing an error condition if that occurs     * in pass two or in a critical expression.     */    long (*segbase) (long segment);    /*     * This procedure is called to allow the output driver to     * process its own specific directives. When called, it has the     * directive word in `directive' and the parameter string in     * `value'. It is called in both assembly passes, and `pass'     * will be either 1 or 2.     *     * This procedure should return zero if it does not _recognise_     * the directive, so that the main program can report an error.     * If it recognises the directive but then has its own errors,     * it should report them itself and then return non-zero. It     * should also return non-zero if it correctly processes the     * directive.     */    int (*directive) (char *directive, char *value, int pass);    /*     * This procedure is called before anything else - even before     * the "init" routine - and is passed the name of the input     * file from which this output file is being generated. It     * should return its preferred name for the output file in     * `outname', if outname[0] is not '\0', and do nothing to     * `outname' otherwise. Since it is called before the driver is     * properly initialised, it has to be passed its error handler     * separately.     *     * This procedure may also take its own copy of the input file     * name for use in writing the output file: it is _guaranteed_     * that it will be called before the "init" routine.     *     * The parameter `outname' points to an area of storage     * guaranteed to be at least FILENAME_MAX in size.     */    void (*filename) (char *inname, char *outname, efunc error);    /*     * This procedure is called after assembly finishes, to allow     * the output driver to clean itself up and free its memory.     * Typically, it will also be the point at which the object     * file actually gets _written_.     *     * One thing the cleanup routine should always do is to close     * the output file pointer.     */    void (*cleanup) (int debuginfo);};/* * values for the `type' parameter to an output function. Each one * must have the actual number of _bytes_ added to it. * * Exceptions are OUT_RELxADR, which denote an x-byte relocation * which will be a relative jump. For this we need to know the * distance in bytes from the start of the relocated record until * the end of the containing instruction. _This_ is what is stored * in the size part of the parameter, in this case. * * Also OUT_RESERVE denotes reservation of N bytes of BSS space, * and the contents of the "data" parameter is irrelevant. * * The "data" parameter for the output function points to a "long", * containing the address in question, unless the type is * OUT_RAWDATA, in which case it points to an "unsigned char" * array. */#define OUT_RAWDATA 0x00000000UL#define OUT_ADDRESS 0x10000000UL#define OUT_REL2ADR 0x20000000UL#define OUT_REL4ADR 0x30000000UL#define OUT_RESERVE 0x40000000UL#define OUT_TYPMASK 0xF0000000UL#define OUT_SIZMASK 0x0FFFFFFFUL/* * ------------------------------------------------------------ * The data structure defining a debug format driver, and the * interfaces to the functions therein. * ------------------------------------------------------------ */struct dfmt {        /*     * 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;    /*     * init - called initially to set up local pointer to object format,      * void pointer to implementation defined data, file pointer (which     * probably won't be used, but who knows?), and error function.     */    void (*init) (struct ofmt * of, void * id, FILE * fp, efunc error);    /*     * linenum - called any time there is output with a change of     * line number or file.     */    void (*linenum) (const char * filename, long linenumber, long segto);    /*     * debug_deflabel - called whenever a label is defined. Parameters     * are the same as to 'symdef()' in the output format. This function     * would be called before the output format version.     */    void (*debug_deflabel) (char * name, long segment, long offset,                            int is_global, char * special);    /*     * debug_directive - called whenever a DEBUG directive other than 'LINE'     * is encountered. 'directive' contains the first parameter to the     * DEBUG directive, and params contains the rest. For example,     * 'DEBUG VAR _somevar:int' would translate to a call to this     * function with 'directive' equal to "VAR" and 'params' equal to      * "_somevar:int".     */    void (*debug_directive) (const char * directive, const char * params);    /*     * typevalue - called whenever the assembler wishes to register a type     * for the last defined label.  This routine MUST detect if a type was     * already registered and not re-register it.     */    void (*debug_typevalue) (long type);    /*     * debug_output - called whenever output is required     * 'type' is the type of info required, and this is format-specific     */    void (*debug_output) (int type, void *param);    /*     * cleanup - called after processing of file is complete     */    void (*cleanup) (void);};/* * The type definition macros * for debugging * * low 3 bits: reserved * next 5 bits: type * next 24 bits: number of elements for arrays (0 for labels) */#define TY_UNKNOWN 0x00#define TY_LABEL   0x08#define TY_BYTE    0x10#define TY_WORD    0x18#define TY_DWORD   0x20#define TY_FLOAT   0x28#define TY_QWORD   0x30#define TY_TBYTE   0x38#define TY_COMMON  0xE0#define TY_SEG     0xE8#define TY_EXTERN  0xF0#define TY_EQU     0xF8#define TYM_TYPE(x) ((x) & 0xF8)#define TYM_ELEMENTS(x) (((x) & 0xFFFFFF00) >> 8)#define TYS_ELEMENTS(x)  ((x) << 8)/* * ----- * Other * ----- *//* * This is a useful #define which I keep meaning to use more often: * the number of elements of a statically defined array. */#define elements(x)     ( sizeof(x) / sizeof(*(x)) )extern int tasm_compatible_mode;/* * This declaration passes the "pass" number to all other modules * "pass0" assumes the values: 0, 0, ..., 0, 1, 2 * where 0 = optimizing pass *       1 = pass 1 *       2 = pass 2 */extern int pass0;	/* this is globally known */extern int optimizing;#endif

⌨️ 快捷键说明

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