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

📄 outas386.c

📁 C编译器 ,简单的一个C语言的编译器。
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * 68K/386 32-bit C compiler.
 *
 * copyright (c) 1997, David Lindauer
 * 
 * This compiler is intended for educational use.  It may not be used
 * for profit without the express written consent of the author.
 *
 * It may be freely redistributed, as long as this notice remains intact
 * and either the original sources or derived sources 
 * are distributed along with any executables derived from the originals.
 *
 * The author is not responsible for any damages that may arise from use
 * of this software, either idirect or consequential.
 *
 * v1.35 March 1997
 * David Lindauer, gclind01@starbase.spd.louisville.edu
 *
 * Credits to Mathew Brandt for original K&R C compiler
 *
 */
#include        <stdio.h>
#include				<ctype.h>
#include        "expr.h"
#include        "c.h"
#include        "gen386.h"
#include 				"diag.h"

int skipsize = 0;
int addsize = 0;

typedef struct muldiv {
		struct muldiv * link;
		long value;
		double floatvalue;
		int size;
		int label;
} MULDIV;
/*      variable initialization         */

char segregs[] = "CSDSESFSGSSS";

extern char outfile[];
extern int prm_flat;
extern SYM *currentfunc;
extern int prm_cmangle;
extern HASHREC **globalhash;
extern int phiused;
extern long nextlabel;
extern FILE *outputFile;
extern int global_flag;

enum e_gt { nogen, bytegen, wordgen, longgen, floatgen, doublegen, longdoublegen, storagegen,srrefgen };
enum e_sg { noseg, codeseg, dataseg,bssxseg,startupxseg,rundownxseg,cppxseg };

extern int	prm_asmfile;
extern int prm_lines,prm_nasm;

static struct slit *strtab;
static int uses_float;

MULDIV *muldivlink = 0;
enum e_gt	 gentype = nogen;		/* Current DC type */
enum e_sg	 curseg = noseg;		/* Current seg */
int        outcol = 0;				/* Curront col (roughly) */
int newlabel;
int needpointer;
static int nosize = 0;
static int phiput;

/* List of opcodes
 * This list MUST be in the same order as the op_ enums 
 */
ASMNAME oplst[] = { 
	{ "reserved", op_reserved,0 },
	{ "line#", op_reserved,0 },
	{ "label", op_reserved,0 },
	{ "flabel", op_reserved,0 },
	{ "seq@", op_reserved,0 },
	{ "db", op_reserved,0 },
	{ "dd", op_reserved,0 },
	{ "aaa", op_aaa,0 },
	{ "aad", op_aad,0 },
	{ "aam", op_aam,0 },
	{ "aas", op_aas,0 },
	{ "add", op_add,OPE_MATH },
	{ "adc", op_adc,OPE_MATH },
	{ "and", op_and,OPE_MATH },
	{ "arpl", op_arpl,OPE_ARPL },
	{ "bound", op_bound,OPE_BOUND },
	{ "bsf", op_bsf,OPE_BITSCAN },
	{ "bsr", op_bsr,OPE_BITSCAN },
	{ "bswap",op_bswap,OPE_REG32 },
	{ "btc", op_btc,OPE_BIT },
	{ "bt", op_bt,OPE_BIT },
	{ "bts", op_bts,OPE_BIT },
	{ "call", op_call,OPE_CALL },
	{ "cbw", op_cbw,0 },
	{ "cwde", op_cwde,0 },
	{ "cwd", op_cwd, 0 },
	{ "cdq", op_cdq,0 },
	{ "clc", op_clc,0 },
	{ "cld", op_cld,0 },
	{ "cli", op_cli,0 },
	{ "clts", op_clts, 0 },
	{ "cmc", op_cmc, 0 },
	{ "cmp", op_cmp, OPE_MATH },
	{ "cmps", op_cmps, OPE_CMPS },
	{ "cmpsb", op_cmpsb, 0 },
	{ "cmpsw", op_cmpsw, 0 },
	{ "cmpsd", op_cmpsd, 0 },
	{ "daa",op_daa,0 },
	{ "das", op_das,0 },
	{ "dec",op_dec, OPE_INCDEC},
	{ "div", op_div, OPE_RM},
	{ "enter", op_enter, OPE_ENTER},
	{ "hlt", op_hlt, 0 },
	{ "idiv", op_idiv, OPE_RM },
	{ "imul", op_imul, OPE_IMUL },
	{ "in", op_in, OPE_IN },
	{ "inc", op_inc, OPE_INCDEC },
	{ "ins", op_ins, OPE_INS },
	{ "insb", op_insb, 0 },
	{ "insw", op_insw, 0 },
	{ "insd", op_insd, 0 },
	{ "int" , op_int, OPE_IMM8 },
	{ "into", op_into, 0 },
	{ "invd", op_invd, 0 },
	{ "iret", op_iret, 0},
	{ "iretd", op_iretd, 0},
	{ "ja", op_ja, OPE_RELBRA},
	{ "jnbe", op_jnbe, OPE_RELBRA},
	{ "jae", op_jae, OPE_RELBRA},
	{ "jnb", op_jnb, OPE_RELBRA},
	{ "jnc", op_jnc, OPE_RELBRA},
	{ "jb", op_jb, OPE_RELBRA},
	{ "jc", op_jc, OPE_RELBRA},
	{ "jnae", op_jnae, OPE_RELBRA},
	{ "jbe", op_jbe, OPE_RELBRA},
	{ "jna", op_jna, OPE_RELBRA},
	{ "jecxz", op_jecxz, OPE_RELBR8},
	{ "je",op_je, OPE_RELBRA },
	{ "jg",op_jg, OPE_RELBRA },
	{ "jnle",op_jnle, OPE_RELBRA },
	{ "jl",op_jl, OPE_RELBRA },
	{ "jnge",op_jnge, OPE_RELBRA },
	{ "jge", op_jge, OPE_RELBRA },
	{ "jnl", op_jnl, OPE_RELBRA },
	{ "jle", op_jle, OPE_RELBRA },
	{ "jng", op_jng, OPE_RELBRA },
	{ "jne", op_jne, OPE_RELBRA },
	{ "jo", op_jo, OPE_RELBRA },
	{ "jno", op_jno, OPE_RELBRA },
	{ "jp", op_jp, OPE_RELBRA },
	{ "jpe", op_jpe, OPE_RELBRA },
	{ "jpo", op_jpo, OPE_RELBRA },
	{ "js", op_js, OPE_RELBRA} ,
	{ "jns", op_jns, OPE_RELBRA },
	{ "jmp", op_jmp, OPE_JMP },
	{ "lahf", op_lahf, 0 },
	{ "lar", op_lar, OPE_REGRM },
	{ "lds", op_lds, OPE_LOADSEG },
	{ "les", op_les, OPE_LOADSEG },
	{ "lfs", op_lfs, OPE_LOADSEG },
	{ "lgs", op_lgs, OPE_LOADSEG },
	{ "lss", op_lss, OPE_LOADSEG },
	{ "lea", op_lea, OPE_REGRM },
	{ "leave", op_leave, 0 },
	{ "lgdt", op_lgdt, OPE_LGDT },
	{ "lidt", op_lidt, OPE_LIDT },
	{ "lldt", op_lldt, OPE_RM16 },
	{ "lmsw", op_lmsw, OPE_RM16 },
	{ "lock", op_lock, 0 },
	{ "lods", op_lods, OPE_LODS },
	{ "lodsb", op_lodsb, 0 },
	{ "lodsw", op_lodsw, 0 },
	{ "lodsd", op_lodsd, 0 },
	{ "loop",op_loop, OPE_RELBR8 },
	{ "loope",op_loope, OPE_RELBR8 },
	{ "loopz",op_loopz, OPE_RELBR8 },
	{ "loopne",op_loopne, OPE_RELBR8 },
	{ "loopnz",op_loopnz, OPE_RELBR8 },
	{ "lsl", op_lsl, OPE_REGRM },
	{ "ltr", op_ltr, OPE_RM16 },
	{ "mov", op_mov, OPE_MOV },
	{ "movs", op_movs, OPE_MOVS },
	{ "movsb", op_movsb, 0 },
	{ "movsw", op_movsw, 0 },
	{ "movsd", op_movsd, 0 },
	{ "movsx", op_movsx, OPE_MOVSX} ,
	{ "movzx", op_movzx, OPE_MOVSX} ,
	{ "mul", op_mul, OPE_RM },
	{ "neg", op_neg, OPE_RM },
	{ "not", op_not, OPE_RM },
	{ "nop", op_nop, 0 },
	{ "or", op_or,OPE_MATH },
	{ "out", op_out,OPE_OUT },
	{ "outs", op_outs, OPE_OUTS },
	{ "outsb", op_outsb, 0 },
	{ "outsw", op_outsw, 0 },
	{ "outsd", op_outsd, 0 },
	{ "pop",op_pop, OPE_PUSHPOP },
	{ "popa", op_popa, 0 },
	{ "popad", op_popad, 0 },
	{ "popf", op_popf, 0 },
	{ "popfd", op_popfd, 0 },
	{ "push",op_push, OPE_PUSHPOP },
	{ "pusha", op_pusha, 0 },
	{ "pushad", op_pushad, 0 },
	{ "pushf", op_pushf, 0 },
	{ "pushfd", op_pushfd, 0 },
	{ "rcl", op_rcl, OPE_SHIFT },
	{ "rcr", op_rcr, OPE_SHIFT },
	{ "rol", op_rol, OPE_SHIFT },
	{ "ror", op_ror, OPE_SHIFT },
	{ "rep", op_rep, 0 },
	{ "repne", op_repne, 0 },
	{ "repe", op_repe, 0 },
	{ "repnz", op_repnz, 0 },
	{ "repz", op_repz, 0 },
	{ "ret", op_ret, OPE_RET },
	{ "sahf", op_sahf, 0 },
	{ "sal", op_sal, OPE_SHIFT },
	{ "sar", op_sar, OPE_SHIFT },
	{ "shl", op_shl, OPE_SHIFT },
	{ "shr", op_shr, OPE_SHIFT },
	{ "sbb", op_sbb,OPE_MATH },
	{ "scas", op_scas, OPE_SCAS },
	{ "scasb", op_scasb, 0 },
	{ "scasw", op_scasw, 0 },
	{ "scasd", op_scasd, 0 },
	{ "seta", op_seta, OPE_SET},
	{ "setnbe", op_setnbe, OPE_SET},
	{ "setae", op_setae, OPE_SET},
	{ "setnb", op_setnb, OPE_SET},
	{ "setnc", op_setnc, OPE_SET},
	{ "setb", op_setb, OPE_SET},
	{ "setc", op_setc, OPE_SET},
	{ "setnae", op_setnae, OPE_SET},
	{ "setbe", op_setbe, OPE_SET},
	{ "setna", op_setna, OPE_SET},
	{ "sete",op_sete, OPE_SET },
	{ "setg",op_setg, OPE_SET },
	{ "setnle",op_setnle, OPE_SET },
	{ "setl",op_setl, OPE_SET },
	{ "setnge",op_setnge, OPE_SET },
	{ "setge", op_setge, OPE_SET },
	{ "setnl", op_setnl, OPE_SET },
	{ "setle", op_setle, OPE_SET },
	{ "setng", op_setng, OPE_SET },
	{ "setne", op_setne, OPE_SET },
	{ "seto", op_seto, OPE_SET },
	{ "setno", op_setno, OPE_SET },
	{ "setp", op_setp, OPE_SET },
	{ "setpe", op_setpe, OPE_SET },
	{ "setpo", op_setpo, OPE_SET },
	{ "sets", op_sets, OPE_SET} ,
	{ "setns", op_setns, OPE_SET },
	{ "sgdt", op_sgdt, OPE_LGDT },
	{ "sidt", op_sidt, OPE_LIDT },
	{ "sldt", op_sldt, OPE_RM16 },
	{ "smsw", op_smsw, OPE_RM16 },
	{ "shld", op_shld, OPE_SHLD },
	{ "shrd", op_shrd, OPE_SHLD },
	{ "stc", op_stc, 0 },
	{ "std", op_std, 0 },
	{ "sti", op_sti, 0 },
	{ "stos", op_stos, OPE_STOS },
	{ "stosb", op_stosb, 0 },
	{ "stosw", op_stosw, 0 },
	{ "stosd", op_stosd, 0 },
	{ "str", op_str, OPE_RM16 },
	{ "sub", op_sub, OPE_MATH },
	{ "test", op_test, OPE_TEST },
	{ "verr", op_verr, OPE_RM16 },
	{ "verw", op_verw, OPE_RM16 },
	{ "wait", op_wait, 0 },
	{ "wbinvd", op_wbinvd, 0 },
	{ "xchg", op_xchg, OPE_XCHG },
	{ "xlat", op_xlat, OPE_XLAT },
	{ "xlatb", op_xlatb, 0 },
	{ "xor", op_xor,OPE_MATH },
	{ "f2xm1", op_f2xm1, 0 },
	{ "fabs", op_fabs, 0 },
	{ "fadd", op_fadd, OPE_FMATH },
	{ "faddp", op_faddp, OPE_FMATHP },
	{ "fiadd", op_fiadd, OPE_FMATHI },
	{ "fchs", op_fchs, 0 },
	{ "fclex", op_fclex, 0 },
	{ "fnclex", op_fnclex, 0 },
	{ "fcom", op_fcom, OPE_FCOM },
	{ "fcomp", op_fcomp, OPE_FCOM },
	{ "fcompp", op_fcompp, 0 },
	{ "fcos", op_fcos, 0 },
	{ "fdecstp", op_fdecstp, 0 },
	{ "fdiv", op_fdiv, OPE_FMATH },
	{ "fdivp", op_fdivp, OPE_FMATHP },
	{ "fidiv", op_fidiv, OPE_FMATHI },
	{ "fdivr", op_fdivr, OPE_FMATH },
	{ "fdivrp", op_fdivrp, OPE_FMATHP },
	{ "fidivr", op_fidivr, OPE_FMATHI },
	{ "ffree", op_ffre, OPE_FREG },
	{ "ficom", op_ficom, OPE_FICOM },
	{ "ficomp", op_ficomp, OPE_FICOM },
	{ "fild", op_fild, OPE_FILD },
	{ "fincstp", op_fincstp, 0 },
	{ "finit", op_finit, 0 },
	{ "fninit", op_fninit, 0 },
	{ "fist", op_fist, OPE_FIST },
	{ "fistp", op_fistp, OPE_FILD },
	{ "fld", op_fld, OPE_FLD },
	{ "fldz", op_fldz, 0},
	{ "fldpi", op_fldpi, 0},
	{ "fld1", op_fld1, 0},
	{ "fldl2t", op_fld2t, 0},
	{ "fldl2e", op_fld2e, 0},
	{ "fldlg2", op_fldlg2, 0},
	{ "fldln2", op_fldln2, 0},
	{ "fldcw", op_fldcw, OPE_M16 },
	{ "fldsw", op_fldsw, OPE_M16 },
	{ "fldenv", op_fldenv, OPE_MN },
	{ "fmul", op_fmul, OPE_FMATH},
	{ "fmulp", op_fmulp, OPE_FMATHP},
	{ "fimul", op_fimul, OPE_FMATHI },
	{ "fpatan", op_fpatan, 0 },
	{ "fprem", op_fprem, 0 },
	{ "fprem1", op_fprem1, 0 },
	{ "fptan", op_fptan, 0 },
	{ "frndint", op_frndint, 0 },
	{ "frstor", op_frstor, OPE_MN },
	{ "fsave", op_fsave, OPE_MN },
	{ "fnsave", op_fnsave, OPE_MN },
	{ "fscale", op_fscale, 0 },
	{ "fsin", op_fsin, 0 },
	{ "fsincos", op_fsincos, 0 },
	{ "fsqrt", op_fsqrt, 0 },
	{ "fst", op_fst, OPE_FST},
	{ "fstp", op_fstp, OPE_FSTP},
	{ "fstcw", op_fstcw, OPE_M16},
	{ "fstsw", op_fstsw, OPE_M16},
	{ "fnstcw", op_fnstcw, OPE_M16},
	{ "fnstsw", op_fnstsw, OPE_M16},
	{ "fstenv", op_fstenv, OPE_MN },
	{ "fnstenv", op_fsntenv, OPE_MN },
	{ "fsub", op_fsub, OPE_FMATH},
	{ "fsubp", op_fsubp, OPE_FMATHP},
	{ "fisub", op_fisub, OPE_FMATHI},
	{ "fsubr", op_fsubr, OPE_FMATH},
	{ "fsubrp", op_fsubrp, OPE_FMATHP},
	{ "fisubr", op_fisubr, OPE_FMATHI},
	{ "ftst", op_ftst, 0},
	{ "fucom", op_fucom, OPE_FUCOM },
	{ "fucomp", op_fucomp, OPE_FUCOM },
	{ "fucompp", op_fucompp, 0 },
	{ "fwait", op_fwait, 0 },
	{ "fxam", op_fxam, 0 },
	{ "fxch", op_fxch, OPE_FXCH },
	{ "fxtract", op_fxtract, 0 },
	{ "fyl2x", op_fyl2x, 0 },
	{ "fyl2xp1", op_fyl2xp1, 0 },
	{0,0,0 },
	};
/* Init module */
void outcodeini(void)
{
	strtab = 0;
	gentype = nogen;
	curseg = noseg;
	outcol = 0;
	newlabel = FALSE;
	phiput = FALSE;
}
void nl(void)
/*
 * New line
 */
{    if (prm_asmfile) {
       if(outcol > 0) {
                fputc('\n',outputFile);
                outcol = 0;
                gentype = nogen;
                }
			 if (phiused && !phiput)
								fputc(0x1f,outputFile);
		 }
}
/* Put an opcode
 */
void outop(char *name)
{
	fputc('\t',outputFile);
	while (*name)
		fputc(toupper(*name++),outputFile);
}
void putop(enum e_op op)
{    
	if (prm_nasm) {   
  	skipsize =  (op == op_lea);
  	addsize = (op == op_push);
		if (op == op_fwait) {
			/* NASM uses WAIT instead of FWAIT */
			outop(oplst[op_fwait].word+1);
			return;
		}
	}
	if (op > op_fyl2xp1)
    DIAG("illegal opcode.");
	else
		outop(oplst[op].word);
	uses_float=(op >=op_f2xm1);
}

void putconst(ENODE *offset)
/*
 *      put a constant to the outputFile file.
 */
{       switch( offset->nodetype )
                {
								case en_autoreg:
                case en_autocon:
                case en_icon:
                case en_lcon:
                case en_iucon:

⌨️ 快捷键说明

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