All pastes #416445 Raw Edit

nasm

public cpp v1 · immutable
#416445 ·published 2007-03-30 08:00 UTC
rendered paste body
#define BITS8     0x00000001L#define BITS16    0x00000002L#define BITS32    0x00000004L#define BITS64    0x00000008L	       /* FPU only */#define BITS80    0x00000010L	       /* FPU only */#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 0x000000FFL	       /* all the size attributes */#define NON_SIZE  (~SIZE_MASK)#define TO        0x00000100L          /* reverse effect in FADD, FSUB &c */#define COLON     0x00000200L	       /* operand is followed by a colon *//* type of operand: memory reference, register, etc. */#define MEMORY    0x00204000L#define REGISTER  0x00001000L	       /* register number in 'basereg' */#define IMMEDIATE 0x00002000L#define REGMEM    0x00200000L	       /* for r/m, ie EA, operands */#define REGNORM   0x00201000L	       /* 'normal' reg, qualifies as EA */#define REG8      0x00201001L#define REG16     0x00201002L#define REG32     0x00201004L#define MMXREG    0x00201008L	       /* MMX registers */#define FPUREG    0x01000000L	       /* floating point stack registers */#define FPU0      0x01000800L	       /* FPU stack register zero *//* special register operands: these may be treated differently */#define REG_SMASK 0x00070000L	       /* a mask for the following */#define REG_ACCUM 0x00211000L	       /* accumulator: AL, AX or EAX */#define REG_AL    0x00211001L	       /* REG_ACCUM | BITSxx */#define REG_AX    0x00211002L	       /* ditto */#define REG_EAX   0x00211004L	       /* and again */#define REG_COUNT 0x00221000L	       /* counter: CL, CX or ECX */#define REG_CL    0x00221001L	       /* REG_COUNT | BITSxx */#define REG_CX    0x00221002L	       /* ditto */#define REG_ECX   0x00221004L	       /* another one */#define REG_DX    0x00241002L#define REG_SREG  0x00081002L	       /* any segment register */#define REG_CS    0x01081002L	       /* CS */#define REG_DESS  0x02081002L	       /* DS, ES, SS (non-CS 86 registers) */#define REG_FSGS  0x04081002L	       /* FS, GS (386 extended registers) */#define REG_CDT   0x00101004L	       /* CRn, DRn and TRn */#define REG_CREG  0x08101004L	       /* CRn */#define REG_CR4   0x08101404L	       /* CR4 (Pentium only) */#define REG_DREG  0x10101004L	       /* DRn */#define REG_TREG  0x20101004L	       /* TRn */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 */} operand;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 */	operand oprs[3];	   	       /* the operands, defined as above */	extop *eops;		       /* extended operands */	long times;			       /* repeat count (TIMES prefix) */	int forw_ref;		       /* is there a forward reference? */} insn;struct itemplate {	int opcode;			    /* the token, passed from "parser.c" */	int operands;		    /* number of operands */	long opd[3];		    /* bit flags for operand types */	char *code;			    /* the code it assembles to */	int flags;			    /* some flags */};#define SEG_RELATIVE 1#define SEG_32BIT 2#define SEG_RMREG 4#define SEG_DISP8 8#define SEG_DISP16 16#define SEG_DISP32 32#define SEG_NODISP 64#define SEG_SIGNED 128#define EXPR_REG_START 1#define EXPR_REG_END 124#define EXPR_UNKNOWN 125L	       /* for forward references */#define EXPR_SIMPLE 126L#define EXPR_WRT 127L#define EXPR_SEGBASE 128Lenum {				       /* register names */	R_AH = EXPR_REG_START, R_AL, R_AX, R_BH, R_BL, R_BP, R_BX, R_CH,	R_CL, R_CR0, R_CR2, R_CR3, R_CR4, R_CS, R_CX, R_DH, R_DI, R_DL,	R_DR0, R_DR1, R_DR2, R_DR3, R_DR6, R_DR7, R_DS, R_DX, R_EAX,	R_EBP, R_EBX, R_ECX, R_EDI, R_EDX, R_ES, R_ESI, R_ESP, R_FS,	R_GS, R_MM0, R_MM1, R_MM2, R_MM3, R_MM4, R_MM5, R_MM6, R_MM7,	R_SI, R_SP, R_SS, R_ST0, R_ST1, R_ST2, R_ST3, R_ST4, R_ST5,	R_ST6, R_ST7, R_TR3, R_TR4, R_TR5, R_TR6, R_TR7, REG_ENUM_LIMIT};enum {				       /* instruction names */	I_AAA, I_AAD, I_AAM, I_AAS, I_ADC, I_ADD, I_AND, I_ARPL,	I_BOUND, I_BSF, I_BSR, I_BSWAP, I_BT, I_BTC, I_BTR, I_BTS,	I_CALL, I_CBW, I_CDQ, I_CLC, I_CLD, I_CLI, I_CLTS, I_CMC, I_CMP,	I_CMPSB, I_CMPSD, I_CMPSW, I_CMPXCHG, I_CMPXCHG486, I_CMPXCHG8B,	I_CPUID, I_CWD, I_CWDE, I_DAA, I_DAS, I_DB, I_DD, I_DEC, I_DIV,	I_DQ, I_DT, I_DW, I_EMMS, I_ENTER, I_EQU, I_F2XM1, I_FABS,	I_FADD, I_FADDP, I_FBLD, I_FBSTP, I_FCHS, I_FCLEX, I_FCMOVB,	I_FCMOVBE, I_FCMOVE, I_FCMOVNB, I_FCMOVNBE, I_FCMOVNE,	I_FCMOVNU, I_FCMOVU, I_FCOM, I_FCOMI, I_FCOMIP, I_FCOMP,	I_FCOMPP, I_FCOS, I_FDECSTP, I_FDISI, I_FDIV, I_FDIVP, I_FDIVR,	I_FDIVRP, I_FENI, I_FFREE, I_FIADD, I_FICOM, I_FICOMP, I_FIDIV,	I_FIDIVR, I_FILD, I_FIMUL, I_FINCSTP, I_FINIT, I_FIST, I_FISTP,	I_FISUB, I_FISUBR, I_FLD, I_FLD1, I_FLDCW, I_FLDENV, I_FLDL2E,	I_FLDL2T, I_FLDLG2, I_FLDLN2, I_FLDPI, I_FLDZ, I_FMUL, I_FMULP,	I_FNCLEX, I_FNDISI, I_FNENI, I_FNINIT, I_FNOP, I_FNSAVE,	I_FNSTCW, I_FNSTENV, I_FNSTSW, I_FPATAN, I_FPREM, I_FPREM1,	I_FPTAN, I_FRNDINT, I_FRSTOR, I_FSAVE, I_FSCALE, I_FSETPM,	I_FSIN, I_FSINCOS, I_FSQRT, I_FST, I_FSTCW, I_FSTENV, I_FSTP,	I_FSTSW, I_FSUB, I_FSUBP, I_FSUBR, I_FSUBRP, I_FTST, I_FUCOM,	I_FUCOMI, I_FUCOMIP, I_FUCOMP, I_FUCOMPP, I_FXAM, I_FXCH,	I_FXTRACT, I_FYL2X, I_FYL2XP1, I_HLT, I_IBTS, I_ICEBP, I_IDIV,	I_IMUL, I_IN, I_INC, I_INCBIN, I_INSB, I_INSD, I_INSW, I_INT,	I_INT1, I_INT01, I_INT3, I_INTO, I_INVD, I_INVLPG, I_IRET,	I_IRETD, I_IRETW, I_JCXZ, I_JECXZ, I_JMP, I_LAHF, I_LAR, I_LDS,	I_LEA, I_LEAVE, I_LES, I_LFS, I_LGDT, I_LGS, I_LIDT, I_LLDT,	I_LMSW, I_LOADALL, I_LOADALL286, I_LODSB, I_LODSD, I_LODSW,	I_LOOP, I_LOOPE, I_LOOPNE, I_LOOPNZ, I_LOOPZ, I_LSL, I_LSS,	I_LTR, I_MOV, I_MOVD, I_MOVQ, I_MOVSB, I_MOVSD, I_MOVSW,	I_MOVSX, I_MOVZX, I_MUL, I_NEG, I_NOP, I_NOT, I_OR, I_OUT,	I_OUTSB, I_OUTSD, I_OUTSW, I_PACKSSDW, I_PACKSSWB, I_PACKUSWB,	I_PADDB, I_PADDD, I_PADDSB, I_PADDSIW, I_PADDSW, I_PADDUSB,	I_PADDUSW, I_PADDW, I_PAND, I_PANDN, I_PAVEB, I_PCMPEQB,	I_PCMPEQD, I_PCMPEQW, I_PCMPGTB, I_PCMPGTD, I_PCMPGTW,	I_PDISTIB, I_PMACHRIW, I_PMADDWD, I_PMAGW, I_PMULHRW,	I_PMULHRIW, I_PMULHW, I_PMULLW, I_PMVGEZB, I_PMVLZB, I_PMVNZB,	I_PMVZB, I_POP, I_POPA, I_POPAD, I_POPAW, I_POPF, I_POPFD,	I_POPFW, I_POR, I_PSLLD, I_PSLLQ, I_PSLLW, I_PSRAD, I_PSRAW,	I_PSRLD, I_PSRLQ, I_PSRLW, I_PSUBB, I_PSUBD, I_PSUBSB,	I_PSUBSIW, I_PSUBSW, I_PSUBUSB, I_PSUBUSW, I_PSUBW, I_PUNPCKHBW,	I_PUNPCKHDQ, I_PUNPCKHWD, I_PUNPCKLBW, I_PUNPCKLDQ, I_PUNPCKLWD,	I_PUSH, I_PUSHA, I_PUSHAD, I_PUSHAW, I_PUSHF, I_PUSHFD,	I_PUSHFW, I_PXOR, I_RCL, I_RCR, I_RDMSR, I_RDPMC, I_RDTSC,	I_RESB, I_RESD, I_RESQ, I_REST, I_RESW, I_RET, I_RETF, I_RETN,	I_ROL, I_ROR, I_RSM, I_SAHF, I_SAL, I_SALC, I_SAR, I_SBB,	I_SCASB, I_SCASD, I_SCASW, I_SGDT, I_SHL, I_SHLD, I_SHR, I_SHRD,	I_SIDT, I_SLDT, I_SMI, I_SMSW, I_STC, I_STD, I_STI, I_STOSB,	I_STOSD, I_STOSW, I_STR, I_SUB, I_TEST, I_UMOV, I_VERR, I_VERW,	I_WAIT, I_WBINVD, I_WRMSR, I_XADD, I_XBTS, I_XCHG, I_XLATB,	I_XOR, I_CMOVcc, I_Jcc, I_SETcc};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};static int whichreg(long regflags, int regval) {	static int reg32[] = {		R_EAX, R_ECX, R_EDX, R_EBX, R_ESP, R_EBP, R_ESI, R_EDI };		static int reg16[] = {			R_AX, R_CX, R_DX, R_BX, R_SP, R_BP, R_SI, R_DI };			static int reg8[] = {				R_AL, R_CL, R_DL, R_BL, R_AH, R_CH, R_DH, R_BH };				static int sreg[] = {					R_ES, R_CS, R_SS, R_DS, R_FS, R_GS, 0, 0 };					static int creg[] = {						R_CR0, 0, R_CR2, R_CR3, R_CR4, 0, 0, 0 };						static int dreg[] = {							R_DR0, R_DR1, R_DR2, R_DR3, 0, 0, R_DR6, R_DR7 };							static int treg[] = {								0, 0, 0, R_TR3, R_TR4, R_TR5, R_TR6, R_TR7 };								static int fpureg[] = {									R_ST0, R_ST1, R_ST2, R_ST3, R_ST4, R_ST5, R_ST6, R_ST7 };									static int mmxreg[] = {										R_MM0, R_MM1, R_MM2, R_MM3, R_MM4, R_MM5, R_MM6, R_MM7 };										if (!(REG_AL & ~regflags))											return R_AL;										if (!(REG_AX & ~regflags))											return R_AX;										if (!(REG_EAX & ~regflags))											return R_EAX;										if (!(REG_DX & ~regflags))											return R_DX;										if (!(REG_CL & ~regflags))											return R_CL;										if (!(REG_CX & ~regflags))											return R_CX;										if (!(REG_ECX & ~regflags))											return R_ECX;										if (!(REG_CR4 & ~regflags))											return R_CR4;										if (!(FPU0 & ~regflags))											return R_ST0;										if (!(REG_CS & ~regflags))											return R_CS;										if (!(REG_DESS & ~regflags))											return (regval == 0 || regval == 2 || regval == 3 ? sreg[regval] : 0);										if (!(REG_FSGS & ~regflags))											return (regval == 4 || regval == 5 ? sreg[regval] : 0);										if (!((REGMEM|BITS8) & ~regflags))											return reg8[regval];										if (!((REGMEM|BITS16) & ~regflags))											return reg16[regval];										if (!((REGMEM|BITS32) & ~regflags))											return reg32[regval];										if (!(REG_SREG & ~regflags))											return sreg[regval];										if (!(REG_CREG & ~regflags))											return creg[regval];										if (!(REG_DREG & ~regflags))											return dreg[regval];										if (!(REG_TREG & ~regflags))											return treg[regval];										if (!(FPUREG & ~regflags))											return fpureg[regval];										if (!(MMXREG & ~regflags))											return mmxreg[regval];										return 0;}static char *reg_names[] = {	       /* register names, as strings */	"ah", "al", "ax", "bh", "bl", "bp", "bx", "ch", "cl",	"cr0", "cr2", "cr3", "cr4", "cs", "cx", "dh", "di", "dl", "dr0",	"dr1", "dr2", "dr3", "dr6", "dr7", "ds", "dx", "eax", "ebp",	"ebx", "ecx", "edi", "edx", "es", "esi", "esp", "fs", "gs",	"mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", "si",	"sp", "ss", "st0", "st1", "st2", "st3", "st4", "st5", "st6",	"st7", "tr3", "tr4", "tr5", "tr6", "tr7"};static char *insn_names[] = {	       /* instruction names, as strings */	"aaa", "aad", "aam", "aas", "adc", "add", "and", "arpl",	"bound", "bsf", "bsr", "bswap", "bt", "btc", "btr", "bts",	"call", "cbw", "cdq", "clc", "cld", "cli", "clts", "cmc", "cmp",	"cmpsb", "cmpsd", "cmpsw", "cmpxchg", "cmpxchg486", "cmpxchg8b",	"cpuid", "cwd", "cwde", "daa", "das", "db", "dd", "dec", "div",	"dq", "dt", "dw", "emms", "enter", "equ", "f2xm1", "fabs",	"fadd", "faddp", "fbld", "fbstp", "fchs", "fclex", "fcmovb",	"fcmovbe", "fcmove", "fcmovnb", "fcmovnbe", "fcmovne",	"fcmovnu", "fcmovu", "fcom", "fcomi", "fcomip", "fcomp",	"fcompp", "fcos", "fdecstp", "fdisi", "fdiv", "fdivp", "fdivr",	"fdivrp", "feni", "ffree", "fiadd", "ficom", "ficomp", "fidiv",	"fidivr", "fild", "fimul", "fincstp", "finit", "fist", "fistp",	"fisub", "fisubr", "fld", "fld1", "fldcw", "fldenv", "fldl2e",	"fldl2t", "fldlg2", "fldln2", "fldpi", "fldz", "fmul", "fmulp",	"fnclex", "fndisi", "fneni", "fninit", "fnop", "fnsave",	"fnstcw", "fnstenv", "fnstsw", "fpatan", "fprem", "fprem1",	"fptan", "frndint", "frstor", "fsave", "fscale", "fsetpm",	"fsin", "fsincos", "fsqrt", "fst", "fstcw", "fstenv", "fstp",	"fstsw", "fsub", "fsubp", "fsubr", "fsubrp", "ftst", "fucom",	"fucomi", "fucomip", "fucomp", "fucompp", "fxam", "fxch",	"fxtract", "fyl2x", "fyl2xp1", "hlt", "ibts", "icebp", "idiv",	"imul", "in", "inc", "incbin", "insb", "insd", "insw", "int",	"int1", "int01", "int3", "into", "invd", "invlpg", "iret",	"iretd", "iretw", "jcxz", "jecxz", "jmp", "lahf", "lar", "lds",	"lea", "leave", "les", "lfs", "lgdt", "lgs", "lidt", "lldt",	"lmsw", "loadall", "loadall286", "lodsb", "lodsd", "lodsw",	"loop", "loope", "loopne", "loopnz", "loopz", "lsl", "lss",	"ltr", "mov", "movd", "movq", "movsb", "movsd", "movsw",	"movsx", "movzx", "mul", "neg", "nop", "not", "or", "out",	"outsb", "outsd", "outsw", "packssdw", "packsswb", "packuswb",	"paddb", "paddd", "paddsb", "paddsiw", "paddsw", "paddusb",	"paddusw", "paddw", "pand", "pandn", "paveb", "pcmpeqb",	"pcmpeqd", "pcmpeqw", "pcmpgtb", "pcmpgtd", "pcmpgtw",	"pdistib", "pmachriw", "pmaddwd", "pmagw", "pmulhrw",	"pmulhriw", "pmulhw", "pmullw", "pmvgezb", "pmvlzb", "pmvnzb",	"pmvzb", "pop", "popa", "popad", "popaw", "popf", "popfd",	"popfw", "por", "pslld", "psllq", "psllw", "psrad", "psraw",	"psrld", "psrlq", "psrlw", "psubb", "psubd", "psubsb",	"psubsiw", "psubsw", "psubusb", "psubusw", "psubw", "punpckhbw",	"punpckhdq", "punpckhwd", "punpcklbw", "punpckldq", "punpcklwd",	"push", "pusha", "pushad", "pushaw", "pushf", "pushfd",	"pushfw", "pxor", "rcl", "rcr", "rdmsr", "rdpmc", "rdtsc",	"resb", "resd", "resq", "rest", "resw", "ret", "retf", "retn",	"rol", "ror", "rsm", "sahf", "sal", "salc", "sar", "sbb",	"scasb", "scasd", "scasw", "sgdt", "shl", "shld", "shr", "shrd",	"sidt", "sldt", "smi", "smsw", "stc", "std", "sti", "stosb",	"stosd", "stosw", "str", "sub", "test", "umov", "verr", "verw",	"wait", "wbinvd", "wrmsr", "xadd", "xbts", "xchg", "xlatb",	"xor"};static char *icn[] = {		       /* conditional instructions */	"cmov", "j", "set"};static int ico[] = {		       /* and the corresponding opcodes */	I_CMOVcc, I_Jcc, I_SETcc};static char *conditions[] = {	       /* condition code names */	"a", "ae", "b", "be", "c", "e", "g", "ge", "l", "le", "na", "nae",	"nb", "nbe", "nc", "ne", "ng", "nge", "nl", "nle", "no", "np",	"ns", "nz", "o", "p", "pe", "po", "s", "z"};static char *whichcond(int condval) {	static int conds[] = {		C_O, C_NO, C_C, C_NC, C_Z, C_NZ, C_NA, C_A,		C_S, C_NS, C_PE, C_PO, C_L, C_NL, C_NG, C_G	};	return conditions[conds[condval]];}