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

📄 picddxhi-tech.c

📁 利用HI-TECH_PICC生成的*.lst文件在Proteus_里调试PIC单片机的.ddx翻译程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	int cr;

	//将输入串复制到新空间
	buf =HeapAlloc(Heap1,0,strlen(instr));
	strcpy(buf, instr);
	p =strstr(buf, scmp);
	if(!p){  //assigned注释是否有效
		HeapFree(Heap1, 0, buf);
		return 0;
	}
	p +=strlen(scmp);  //找到符号名
	p1 =strtok(buf, " \t\n");
	p1 +=strlen(p1) +1;
	p1 =strtok(NULL, " \t\n");
	strcpy(item->variable, p1);  //输出变量名
	p1 =strtok(p -1, " \t\n");
	strcpy(item->symbo, p1);  //输出符号名
	HeapFree(Heap1, 0, buf);
	return 1;
}

//翻译一个assigned注释到新串
int TranslateAssigned(char *instr, PARRAY *SymbolTable, char *outstr)
{
	const char scmp[] =" assigned to ";
	char *p, *p1;
	char buf[1024];
	char s[32];
	long i;
	SYMBOITEM *symp;
	int cr;
	char c;

	//将输入串复制到新空间
	strcpy(buf, instr);
	p =strstr(buf, scmp);
	if(!p){  //assigned注释是否有效
		return 0;
	}
	p +=strlen(scmp);  //找到符号名
	p1 =strtok(buf, " \t\n");
	p1 +=strlen(p1) +1;
	p1 =strtok(NULL, " \t\n");
	strcpy(outstr, ",,,                    ;");
	strcat(outstr, p1);  //输出变量名
	strcat(outstr, " address: ");
	p1 =strpbrk(p, "+-");
	c =p1[0];
	p1[0] =0;
	//找到对应符号名
	for(i =0; i <SymbolTable->cnt; i++){
		symp =SymbolTable->p[i];
		cr =strcmp(p, symp->name);
		if(!cr){
			sprintf(s, "%04lX", symp->address);
			strcat(outstr, s);  //输出相应地址
			p1[0] =c;
			strcat(outstr, p1);
			return 1;
		}
	}
	return 0;
}

//置换符号名到变量名
int CovertSymbo(char *instr, char *outstr)
{
	int i;
	ASSIGNEDITEM *agnp;
	char *sp, *sp1;
	char buf[256];

	strcpy(outstr, instr);
	for(i =0; i <gAssignedTable.cnt; i++){
		agnp =gAssignedTable.p[i];
		sp =strstr(outstr, agnp->symbo);
		if(sp){
			sp1 =sp +strlen(agnp->symbo);  //找到符号名尾
			strcpy(buf, sp1);
			sp[0] =0;  //从符号名前截断串
			strcat(outstr, agnp->variable);  //补上变量名
			strcat(outstr, buf);
			break;
		}
	}
	return 1;
}

//输出到文件
int fPutToFile(char *buf, FILE *file)
{
#ifdef _PUTINFO
	fprintf(stderr, buf);
#endif
	fputs(buf, file);
	return 1;
}

void debugout(char *s)
{
	fprintf(stderr,"%s",s);

}

//翻译一行文本到.SDI文件
void TranslateLine(FILE *outfile,char *buffer)
{
	const char sCH[] ="////";
	static char slable[256] ={0};	//保存前一个跳转标号
	char savebuf[1027];
	char buf[256];
	char *bp;
	int r;
	MATERIAL matl;
	ASSIGNEDITEM *pagnitem;

	r =AnalyseLine(buffer, &matl);
	switch(r){
		case 1:  //指令,文本包括:行号,地址,机器码,指令
		//生成一行调试信息
		sprintf(savebuf,"%06X",matl.Address);  //Address
		strcat(savebuf,",");
		strcat(savebuf,matl.Code);  //Code
		strcat(savebuf,",");
		if(strlen(slable)){
			strcat(savebuf,slable);  //Lable
			strcat(savebuf,",");
			strcat(savebuf,slable);  //在汇编语句前添加跳转标号
			strcat(savebuf,":");
			slable[0] =0;  //清除跳转标号
		}else{
			strcat(savebuf,",");
		}
		if(gAssignedTable.cnt) CovertSymbo(matl.Text, buf);  //当有符号定义时进行符号置换
		else strcpy(buf, matl.Text);  //Operation
		strcat(savebuf, buf);
		if(savebuf[strlen(savebuf) -1] !='\n') strcat(savebuf, "\n");
		fPutToFile(savebuf, outfile);
		break;

		case 2:  //跳转标号,文本包括:行号,地址,标识符
		if(!strnicmp(matl.Text, "ds", 2)){  //处理ds标识
			sprintf(buf,"%06X",matl.Address);  //Address
			strcpy(savebuf,",,,");
			strcat(savebuf,sCH);
			strcat(savebuf,";");
			strcat(savebuf,slable);  //在变量前添加标号
			strcat(savebuf," address: ");
			slable[0] =0;  //清除标号
			strcat(savebuf,buf);
			strcat(savebuf,"    ");
			strcat(savebuf,matl.Text);
			fPutToFile(savebuf, outfile);
		}
		else strcpy(slable, matl.Text);
		break;

		case 3:  //陈述,文本包括:行号,陈述
		switch(AnalyseComment(matl.Text)){
			case 1:  //普通注释
			strcpy(savebuf,",,,");
			strcat(savebuf,sCH);
			strcat(savebuf, matl.Text);
			fPutToFile(savebuf, outfile);
			break;
			case 3:  //assigned注释
			TranslateAssigned(matl.Text, &gSymboTable, savebuf);
			pagnitem =HeapAlloc(Heap1,0,sizeof(ASSIGNEDITEM));
			if(!pagnitem){
				fprintf(stderr, "Can't alloc memory.");
				exit(2);
			}
			TranslateAssignedToItem(matl.Text, &gAssignedTable, pagnitem);
			PArrayAdd(&gAssignedTable, pagnitem);
			fPutToFile(savebuf, outfile);
			break;
		}
		break;

		case 4:  //接上一行,文本包括:起始空格,文本
		fseek(outfile, -2, SEEK_CUR);  //接上一行文本
		strcpy(savebuf, matl.Text);
		if(savebuf[strlen(savebuf) -1] !='\n') strcat(savebuf, "\n");
		fPutToFile(savebuf, outfile);
		break;

		case 5:  //说明,文本包括:无起始空格的说明
		strcpy(savebuf,",,,");
		strcat(savebuf, matl.Text);
		fPutToFile(savebuf, outfile);
		break;

		case 7:  //FNSIZE陈述
#ifdef _PUTINFO
		PutAssignedTable(&gAssignedTable);
#endif
		PArrayClear(&gAssignedTable);  //清除置换表,为下一个程序作准备
		break;
	}
}

//分开完全文件名的各个部分
typedef struct tagSEPARATEFULLNAME{
	char path[MAX_PATH];  //路径
	char name[MAX_PATH];  //主文件名
	char ext[MAX_PATH];  //扩展名
} SEPARATEFULLNAME;
void SeparateFullName(char *buffer, SEPARATEFULLNAME *spname)
{
	char buf[MAX_PATH];
	char *cp, *cp1;

	strcpy(buf, buffer);
	//分离短文件名
	cp =strrchr(buf, '\\');
	if(!cp) cp =buf;
	else cp++;
	//分离扩展文件名
	cp1 =strrchr(cp, '.');
	if(cp1){
		*cp1 =0;
		cp1++;
		strcpy(spname->ext, cp1);
	}else strcpy(spname->ext, "");
	//分离主文件名
	strcpy(spname->name, cp);
	//分离路径
	if(cp ==buf) strcpy(spname->path, "");
	else{
		cp--;
		*cp =0;
		strcpy(spname->path, buf);
	}
}

typedef struct tagLSTINFO{
	char Name[MAX_PATH];  //文件名
	long Address;  //起始地址
} LSTINFO;
#define	MAX_LST		32  //最大.LST文件数
char sdifilename[MAX_PATH];
LSTINFO *LstInfoTable[MAX_LST];  //.LST文件信息结构数据(LSTINFO)指针数组
int fcnt;  //.LST文件数量
LSTINFO *pLstInfo;
PARRAY gSymboTable;  //符号表
//Main route
int main(int argc,char *argv[])
{
	const char sAS[] ={"HI-TECH Software PICC Macro Assembler"};
	char buffer[1024];
	char lastbuf[1024];
	int i, j;
	int lc = 0;  //The total that lines in input file.
	int rt;
	char *cp, *cp1;
	WIN32_FIND_DATA FindFileData;
	HANDLE fh;
	SEPARATEFULLNAME spname;
	char sOrgPath[MAX_PATH];
	MATERIAL matl;

	if (argc < 2)
	{
	    Usage(argv[0]);
		return 1;
	}
	/* handle the program options */
	HandleOptions(argc,argv);
	Heap1 =HeapCreate(0, 4*1024*1024, 0);
	if(!Heap1) fprintf(stderr, "Can't create Heap.");
	
	//得到所有.LST文件名
	fcnt =0;
	SeparateFullName(argv[1], &spname);
	strcpy(buffer, spname.path);
	if(strlen(buffer)) strcat(buffer, "\\*.lst");  //若有路径名则添加'\'
	else strcpy(buffer, "*.lst");
	fh =FindFirstFile(buffer, &FindFileData);  //寻找第一个.LST文件
	if(fh ==INVALID_HANDLE_VALUE){
		fprintf(stderr, "Can not find .LST file.");
		return 1;
	}
	LstInfoTable[fcnt] =HeapAlloc(Heap1,0,sizeof(LSTINFO));
	if(strlen(spname.path)){  //若有路径名则合并成完全文件名
		strcpy(LstInfoTable[fcnt]->Name, spname.path);
		strcat(LstInfoTable[fcnt]->Name, "\\");
		strcat(LstInfoTable[fcnt]->Name, FindFileData.cFileName);
	}else
		strcpy(LstInfoTable[fcnt]->Name, FindFileData.cFileName);
	fcnt++;
	while(FindNextFile(fh, &FindFileData)){  //寻找接下来的.LST文件
		LstInfoTable[fcnt] =HeapAlloc(Heap1,0,sizeof(LSTINFO));
		if(strlen(spname.path)){
			strcpy(LstInfoTable[fcnt]->Name, spname.path);
			strcat(LstInfoTable[fcnt]->Name, "\\");
			strcat(LstInfoTable[fcnt]->Name, FindFileData.cFileName);
		}else
			strcpy(LstInfoTable[fcnt]->Name, FindFileData.cFileName);
		fcnt++;
	}
	//获得.LST文件首地址
	for(i =0; i< fcnt; i++){
		lstfile = fopen(LstInfoTable[i]->Name,"rt");	/* Open input file. */
		if(!lstfile){
    		fprintf(stderr,"Can not get .lst file.\n");
			return 1;
		}else{
			fprintf(stderr,"Check %s file.\n", LstInfoTable[i]->Name);
		}
		LstInfoTable[i]->Address = fGetFirstAddress(lstfile, buffer);
		fclose(lstfile);
	}
	//根据首地址将.LST文件信息表排序(冒泡排序)
	for(j =fcnt; j >1; j--){
		for(i =0; i< j -1; i++){
			if(LstInfoTable[i]->Address > LstInfoTable[i +1]->Address){  //元素比较
				//元素位置交换
				pLstInfo =LstInfoTable[i];
				LstInfoTable[i] =LstInfoTable[i +1];
				LstInfoTable[i +1] =pLstInfo;
			}
		}
	}

	//根据可执行程序参数生成.SDI文件名
	strcpy(buffer, argv[1]);
	cp =strrchr(buffer, '\\');
	if(!cp) cp =buffer;
	else cp++;
	strcpy(sdifilename, cp);
	//改变文件名
	cp1 =strrchr(sdifilename, '.');  //去掉扩展名
	if(cp1){
		*cp1 =0;
	}
	strcat(sdifilename,".SDI");	//改变扩展名
	//生成完全文件名
	cp =strrchr(buffer, '\\');
	if(!cp) cp =buffer;
	else cp++;
	*cp =0;  //去掉原始文件名的路径
	strcat(buffer, sdifilename);
	strcpy(sdifilename, buffer);
	//创建输出的.SDI文件
	if((sdifile = fopen(sdifilename, "wt"))==NULL){
		fprintf(stderr, "Don't create %s file.\n", sdifilename);
		return 1;
	}else{
		fprintf(stderr, "Create %s file.\n", sdifilename);
	}

	sprintf(buffer,"000000,0000,startup,startup\n");  //复位地址
	fPutToFile(buffer, sdifile);
	rt =PArrayInit(&gSymboTable);  //初始化符号表指针数组
	if(!rt) return 2;
	rt =PArrayInit(&gAssignedTable);  //初始化符号置换表指针数组
	if(!rt) return 2;
	//依次转换.LST文件到.SDI文件
	for(i =0; i< fcnt; i++){
		//打开.LST文件
		lstfile = fopen(LstInfoTable[i]->Name,"rt");  //打开.SDI输出文件
		if(!lstfile){
    		fprintf(stderr,"Can not open .lst file.\n");
			return 1;
		}else{
			fprintf(stderr,"Open %s file to covert.\n", LstInfoTable[i]->Name);
		}
		fGetSymboTable(lstfile, &gSymboTable);  //得到符号表
#ifdef _PUTINFO
		PutSymboTable(&gSymboTable);  //输出符号表
#endif
		//开始转换
		lc =0;
		fseek(lstfile, 0, SEEK_SET);
		sprintf(buffer, "\n,,,/****;FILE: %s****/\n\n", LstInfoTable[i]->Name);  //输出文件名
		fPutToFile(buffer, sdifile);
		while(1){
			rt = fgetline(lstfile, buffer);
    		if(!strncmp(buffer,sAS,strlen(sAS))) break;  //到达汇编开始位置
    	}
		rt = fgetline(lstfile, lastbuf);  //读入第一行
    	do{
    		rt = fgetline(lstfile, buffer);
	    	lc++;
    		if(!strncmp(lastbuf,sAS,strlen(sAS))) break;  //到达汇编结束位置
    		//连接不连续的行文本
			if(AnalyseLine(buffer, &matl) ==4){
				lastbuf[strlen(lastbuf) -1] =0;  //截去换行符
				cp =strtok(buffer, " ");
				if(cp[strlen(cp) -1]!='\n')	cp[strlen(cp)]=' ';
				strcat(lastbuf, cp);
			}else{
	    		TranslateLine(sdifile,lastbuf);
	    		strcpy(lastbuf, buffer);
    		}
    	}while(rt != 0);

		fclose(lstfile);
	}

    fclose(sdifile);
	return 0;
}

⌨️ 快捷键说明

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