www.pudn.com > ASM86_64.rar > main.c


#include 
#include 
#include 

#include "i_attribute.h"
#include "a64-2.h"
#include "error.h"
#include "operand.h"
#include "generate.h"
#include "parse.h"
#include "option.h"

#include "iob.h"



#define AUTHOR_INFO  "Author: mik     QQ:36058179  E-mail: mikdeng@163.com"
#define PROGRAM_INFO "a64: 64-bit assembler for x86-64"
#define VERSION_INFO "version id:  0.1-1-1-0.1" 
#define SUPPORT_INS "support all x86-64's General-Purpose Instruction"	
#define NOT_SUPPORT_INS		\
	"this version not support X87, MMX, XMM and AMD 3DNow! instruction"
#define BETA_INFO    "It's China-Unix beta version" 


#define PRINT_AUTHOR_INFO 	\
		{ fprintf(stdout, "****** %s ******\n", AUTHOR_INFO); } 
#define PRINT_PROGRAM_INFO	\
		{ fprintf(stdout, "%s\n", PROGRAM_INFO); }
#define PRINT_VERSION_INFO 	\
		{ fprintf(stdout, "%s\n", VERSION_INFO); }
#define PRINT_INS_SET_INFO	\
	{ fprintf(stdout, "(%s)\n(%s)\n\n", SUPPORT_INS, NOT_SUPPORT_INS); }

#define PRINT_BETA_INFO	{ 	\
	fprintf(stdout, "\t\t%s\n",	\
	   "*********************************************************"); \
	fprintf(stdout, "\t\t* %s \t*\n", AUTHOR_INFO);			\
	fprintf(stdout, "\t\t* %s \t\t\t*\n", PROGRAM_INFO);		\
	fprintf(stdout, "\t\t* %s \t\t\t\t*\n", VERSION_INFO);		\
	fprintf(stdout, "\t\t* %s \t\t\t\t*\n", BETA_INFO);		\
	fprintf(stdout, "\t\t%s\n\n", \
	   "*********************************************************"); \
}

extern unsigned int current_bits;
extern unsigned long long current_pc;

static char *program_name;
static char *read_fname[10];
static char *write_fname[10];

struct opt_struct opts[] = {
	{ "-help", 0 },
	{ "-verbose", 0 },
	{ "f", 1 },
	{ "o", 1 },
	{ "-print-encode", 0 },
	{ "v", 0 },
	{ "-version", 0 },
	{ 0, 0 }
};


static void usage() 
{
/*	PRINT_AUTHOR_INFO;	*/
	fprintf(stdout, "usage: \n");
	fprintf(stdout, "\ta64 [option] \n");
	fprintf(stdout, "\ta64 --help   for get help\n\n");
	
}

static void help()
{
/*	PRINT_AUTHOR_INFO;	*/
	fputs("\n--help \t\t\tfor get help\n", stdout);
	fputs("--verbose \t\tfor get a64 information\n", stdout);
	fputs("-v\t--version\t for get version info\n", stdout);
	fputs("-f  \tfor get object-format's out-object\n", 
		stdout);
	fputs("-o  \tfor get object-name's out-object\n\n", 
		stdout);

}

static errno_t do_parse_file(char *source_file, char *argv);


int main(int argc, char **argv)
{
	int i = 1;
	int r_i = 0, w_i = 0;
	int print_encode = 0;
	int out_file = 0;

	errno_t errno = 0;

	struct iob read_iob, write_iob;
	int read_fd, write_fd;

	PRINT_BETA_INFO;

	if (argc < 2) {
		usage();
		exit(1);
	}	
	
	program_name = argv[0];

	for (; i < argc; i++) {
		struct parse_opt ret = parse_option(i, argv, opts);
		switch (ret.index) {
		case -1:
			fprintf(stderr, 
				"bad option !!!\n%s --help \t\tfor get help\n",
				program_name);
			exit(1);
			break;
		case IS_FILE:
			read_fname[r_i++] = argv[i];
			write_fname[w_i] = (char *)a64_malloc(80);
			if (do_parse_file(write_fname[w_i++], argv[i])) {
				fprintf(stderr, "the source file " 
					"isn't valid assemble source file\n");

				if (write_fname[w_i-1])
					a64_free(write_fname[w_i-1]);
				exit(1);
			}
			
			break;
		case 0:			/* --help */
			help();
			exit(0);
			break;	
		case 1:			/* --verbose */
			PRINT_AUTHOR_INFO;
			PRINT_PROGRAM_INFO;
			PRINT_VERSION_INFO;
			PRINT_INS_SET_INFO;
			exit(0);
			break;
		case 2:			/* -f */
			if (i >= argc - 1) {
				fputs("bad file-format!!!\n", stderr);
				exit(1);
			}

			i++; break;
		case 3:			/* -o */
			out_file = 1;

			if ((r_i != 1) || (i >= argc - 1)) {
				fprintf(stderr, "out file failed!\n");
				int i = 0;
				for (; i < r_i; i++)
					if (write_fname[i])
						a64_free(write_fname[i]);
				exit(1);
			}

			if (write_fname[w_i-1])
				a64_free(write_fname[w_i-1]);

			write_fname[w_i-1] = argv[++i];
			break;
		case 4:			/* --print-encode */
			print_encode = 1;
			break;
		case 5:			/* -v */
		case 6:			/* --version */
			PRINT_VERSION_INFO;
			exit(0);
			break;
		}
	}
	
	if (r_i == 0) {
		fputs("no input file \n", stderr);
		exit(1);
	}

	for (i = 0; i < r_i; i++) {
		read_fd = open(read_fname[i], O_RDONLY);
		if (read_fd == -1) {
			fputs("open file failed!!\n", stderr);
			exit(1);
		}

		write_fd = open(write_fname[i], 
				O_WRONLY|O_CREAT|O_TRUNC, 0664);
		if (write_fd == -1) {
			fputs("write file failed\n",stderr);
			exit(1);
		}

		init_iob(read_fd, &read_iob);	
		init_iob(write_fd, &write_iob);

		if (errno = analyse_file(&read_iob)) {
			print_err();
			release_resource();
			exit(1);
		}
			
		if (errno = generate(&write_iob)) {
			print_err();
			release_resource();
			exit(1);		
		}

		if (print_encode) {
			fprintf(stdout, "The encode: \n");
			int i = 0;
			while (i < current_pc)
				printf("%x ", 
					(unsigned char)write_iob.buf[i++]);
			printf("\n");
		}


		flush_all_iob(&write_iob);
		fprintf(stdout, "\nOut file is: %s\n\n", write_fname[i]);

		if (out_file == 0)
			if (write_fname[r_i])
				a64_free(write_fname[r_i]);			

		release_resource();
		reset_environment();

		close(read_fd);
		close(write_fd);
	}


	return 0;
}

static errno_t do_parse_file(char *source_file, char *argv)
{
	errno_t errno = 0;
	char str[80];
	int i = 0;
	int no_dot = 1;

	for (; ; argv++) {
		if (is_c(*argv) || is_n(*argv) || *argv == '_') {
			if (i >= 80)
				return ERR_ERROR;
			str[i++] = *argv;
		} else switch (*argv) {
		case '.':
			no_dot = 0;
			str[i] = 0;
			strcpy(source_file, str);
			i = 0; break;
		case 0:
			str[i] = 0;
			if (no_dot) 
				errno = ERR_ERROR;
				
			if ((i == 0) || 
				(!str_cmp(str, "s")) && (!str_cmp(str, "asm")))
				errno = ERR_ERROR;

			return errno;
		default : 
			return ERR_ERROR;
		} 
	} 

	return errno;
}