C语言实现简易LC-3汇编器

        这是笔者的计算系统概论这门课的实验之一,实验内容是实现简易的LC-3汇编器,将汇编码转换为机器码,原理较为简单,即利用两次遍历,第一次获取标签信息,第二次实现转换。但具体用代码实现极其繁琐,特别是不止18个指令要一个一个写,所以把写好的代码放在下面供大家参考,注释也写了,如果有看不懂的或有什么问题可以直接问我。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define MAX_LINE_LENGTH 100

//标签链表结构体,用于储存标签名以及标签位置
typedef struct Lable{
	char * name;
	int pos;
	struct Lable *next;
}Lable;

// Function prototypes
void read_asm_file(const char *filename, char lines[][MAX_LINE_LENGTH], int *num_lines);
void write_output_file(const char *filename, const char *output[], int num_lines);
void assemble(char lines[][MAX_LINE_LENGTH], int num_lines, char *output[]);
char * translate_instruction(char *instruction,int line,Lable *head);
char *bin_transfer(char *str,int bit);
char *reg_num(char *str);
Lable *get_lable_pos(char lines[][MAX_LINE_LENGTH],int line_index);
char *word_ascii(char word);
char **my_strtok(const char *source, char flag);
int getIndexOfSigns(char ch);
long hexToDec(char *source);
void reverse(char* left, char* right);
char* to_binary(int n, int m);

// TODO: Define any additional functions you need to implement the assembler, e.g. the symbol table.



int main(int argc, char *argv[])
//int main()
{
    // Command-line argument parsing
    if (argc != 3)
    {
        fprintf(stderr, "Usage: %s <input_file.asm> <output_file.txt>\n", argv[0]);
        return 1;
    }

    char input_filename[100];
    char output_filename[100];
    strcpy(input_filename, argv[1]);
    strcpy(output_filename, argv[2]);

//	printf("input input_filename:\n");
//	scanf("%s",&input_filename);
//	printf("input output_filename:\n");
//	scanf("%s",&output_filename);

	
    char lines[100][MAX_LINE_LENGTH]; // Assuming a maximum of 100 lines
    int num_lines = 0;
    read_asm_file(input_filename, lines, &num_lines);

    char *output[100]; // Output array of strings
    for (int i = 0; i < 100; i++)
    {
        output[i] = (char *)malloc(MAX_LINE_LENGTH * sizeof(char));
    }

    assemble(lines, num_lines, output);
    write_output_file(output_filename, (const char **)output, num_lines);

    // Free allocated memory
    for (int i = 0; i < 100; i++)
    {
        free(output[i]);
    }

    return 0;
}

void read_asm_file(const char *filename, char lines[][MAX_LINE_LENGTH], int *num_lines)
{
    FILE *file = fopen(filename, "r");
    if (file == NULL)
    {
        fprintf(stderr, "Unable to open file: %s\n", filename);
        exit(1);
    }

    char line[MAX_LINE_LENGTH];
    while (fgets(line, MAX_LINE_LENGTH, file))
    {
        strcpy(lines[*num_lines], line);
        printf("%s",lines[*num_lines]);
        (*num_lines)++;
    }

    fclose(file);
}

void write_output_file(const char *filename, const char *output[], int num_lines)
{
    FILE *file = fopen(filename, "w");
    if (file == NULL)
    {
        fprintf(stderr, "Unable to open file: %s\n", filename);
        exit(1);
    }

    for (int i = 0; i < num_lines; i++)
    {
        fprintf(file, "%s\n", output[i]);
    }

    fclose(file);
}
int trans_line = 1;
void assemble(char lines[][MAX_LINE_LENGTH], int num_lines, char *output[])
{
    // TODO: Implement the assembly process
    // Implement the 2-pass process described in textbook.
    Lable *lable;
    lable = get_lable_pos(lines,num_lines);//第一次遍历创建标签链表
    char *tem_output;
    for (int i = 0; i < num_lines; i++)
    {   	
        tem_output = translate_instruction(lines[i],i+trans_line,lable);//临时指针存转码结果
        strcpy(output[i],tem_output);
        printf("\n%s",output[i]);//打印结果
    }
}

char * translate_instruction(char *instruction,int line,Lable *head)
{
	char *machine_code;//要返回的机器码
	machine_code = (char *)malloc(MAX_LINE_LENGTH * sizeof(char));//分配空间
	char *condition_code;//条件码
	//下面是用到的29个指令
    char str1[] = ".ORIG";
    char str2[] = "ADD";
    char str3[] = "AND";
    char str4[] = "BR";
    	char str4_1[] = "BRN";
    	char str4_2[] = "BRZ";
    	char str4_3[] = "BRP";
    	char str4_4[] = "BRNZ";
    	char str4_5[] = "BRNP";
    	char str4_6[] = "BRZP";
    	char str4_7[] = "BRNZP";//BR子指令
    char str5[] = "JMP";
    char str6[] = "RET";
    char str7[] = "JSR";
    char str8[] = "JSRR";
    char str9[] = "LD";
    char str10[] = "LDI";
    char str11[] = "LDR";
    char str12[] = "LEA";
	char str13[] = "NOT";
	char str14[] = "RTI";
	char str15[] = "ST";
	char str16[] = "STI";
	char str17[] = "STR";
	char str18[] = "TRAP";
	char str19[] = ".BLKW";
	char str20[] = ".STRINGZ";
	char str21[] = ".FILL";
	char str22[] = ".END";
	 
    char ** single ;//用来存分割后的字符串
    char space = ' ';//按空格分割
    char enter = '\n';//按换行分割,因为字符串最后有\n
    char *reg_number = "000";
    char *imm_number = "1";//一些机器码中用到的码
    single = my_strtok(instruction,enter);
    single = my_strtok(single[0],space);//第一次分割,得到各个子字符串
    int bin_num;
    int count;//计数,表示是分割后的第几个字符串
	for(count = 0;;count++)
	{
		if(strcmp(single[count],str1) == 0 || strcmp(single[count],str21) == 0)//.ORIG or .FILL
		{
			single = my_strtok(single[count+1],enter);//去换行操作
			machine_code= bin_transfer(single[0],16);//将语句后面带的数直接转为16位二进制编码
			break;			
		}
		if(strcmp(single[count],str2) == 0 || strcmp(single[count],str3) == 0)//ADD or AND
		{
			if(strcmp(single[count],str2) == 0)
			{
				condition_code = "0001";				
			}
			else
			{
				condition_code = "0101";//先存入指令码,后面类似
			}
			strcpy(machine_code,condition_code);
			count ++;
			if(single[count][0] != '#' && single[count][0] != 'x')//这句并没有多大用处,因为ADD或AND后面两个都是寄存器
			{
				char *ad_binary_1 = reg_num(single[count++]);//判断寄存器
				strcat(machine_code,ad_binary_1);
			}
			if(single[count][0] != '#' && single[count][0] != 'x')
			{
				char *ad_binary_2 = reg_num(single[count++]);
				strcat(machine_code,ad_binary_2);
			}
			single = my_strtok(single[count],enter);
			if(single[0][0] != '#' && single[0][0] != 'x')//检测是立即数还是寄存器
			{
				strcat(machine_code,reg_number);
				char *ad_binary_3 = reg_num(single[0]);
				strcat(machine_code,ad_binary_3);
			}
			else
			{
				strcat(machine_code,imm_number);
				char *ad_bin;
				ad_bin = bin_transfer(single[0],5);
				strcat(machine_code,ad_bin);
			}
			break;
		}
		if(strcmp(single[count],str4) == 0 || strcmp(single[count],str4_1) == 0 || strcmp(single[count],str4_2) == 0 || strcmp(single[count],str4_3) == 0 || strcmp(single[count],str4_4) == 0 || strcmp(single[count],str4_5) == 0 || strcmp(single[count],str4_6) == 0 || strcmp(single[count],str4_7) == 0)
		{
			if(strcmp(single[count],str4) == 0 || strcmp(single[count],str4_7) == 0)//BR or BRNZP
			{
				condition_code = "0000111";						
			}
			if(strcmp(single[count],str4_1) == 0)//BRN
			{
				condition_code = "0000100";
			}
			if(strcmp(single[count],str4_2) == 0)//BRZ
			{
				condition_code = "0000010";
			}
			if(strcmp(single[count],str4_3) == 0)//BRP
			{
				condition_code = "0000001";
			}
			if(strcmp(single[count],str4_4) == 0)//BRNZ
			{
				condition_code = "0000110";
			}
			if(strcmp(single[count],str4_5) == 0)//BRNP
			{
				condition_code = "0000101";
			}
			if(strcmp(single[count],str4_6) == 0)//BRZP
			{
				condition_code = "0000011";
			}
			strcpy(machine_code,condition_code);
			count++;
			single = my_strtok(single[count],enter);
			if(single[0][0] == '#' || single[0][0] == 'x')//检测是立即数还是标签
			{
				char *br_bin = bin_transfer(single[0],9);
				strcat(machine_code,br_bin);
			}
			else
			{
				Lable *p = head;
				char *br_bin_2;
				char *imm_0 = "000000000";
				while(p!= NULL)//遍历标签链表找到对应标签所在位置(行数)
				{
					if(strcmp(single[0],p->name) == 0)
					{
						int sub = p->pos - 1 - line;//标签行数减PC增量减当前行数
						if(sub == 0)
						{
							strcat(machine_code,imm_0);
							break;
						}
						else
						{
							br_bin_2 = to_binary(sub,9);	//得到差值并转为9位二进制编码
							strcat(machine_code,br_bin_2);				
							break;
						}
					}
					p = p->next;
				}				
			}
			break;
		}
		char *jmp_bin_2 = "000000";
		if(strcmp(single[count],str5) == 0 || strcmp(single[count],str6) == 0)//JMP or RET
		{
			if(strcmp(single[count],str5) == 0)
			{
				condition_code = "1100000";
				strcpy(machine_code,condition_code);
				count ++ ;
				single = my_strtok(single[count],enter);
				char *jmp_bin = reg_num(single[0]);	
				strcat(machine_code,jmp_bin);			
				strcat(machine_code,jmp_bin_2);				
			}
			else
			{
				condition_code = "1100000111000000";
				strcpy(machine_code,condition_code);
			}
			break;
		}
		if(strcmp(single[count],str7) == 0 || strcmp(single[count],str8) == 0)//JSR or JSRR
		{
			if(strcmp(single[count],str7) == 0)
			{
				condition_code = "01001";
				strcpy(machine_code,condition_code);
				count ++ ;
				single = my_strtok(single[count],enter);
				if(single[0][0] == '#' || single[0][0] == 'x')
				{
					char *jsr_num_bin  = bin_transfer(single[0],11);
					strcat(machine_code,jsr_num_bin);
				}
				else
				{
					Lable *jsr_p = head;//同样的检测标签并返回,只不过变为了11位
					jsr_p->name = (char *)malloc(100 *sizeof(char));
					char *jsr_bin_2;
					while(jsr_p != NULL)
					{
						if(strcmp(single[0],jsr_p->name) == 0)
						{
							int jsr_sub = jsr_p->pos - 1 - line ;
							jsr_bin_2 = to_binary(jsr_sub,11);	
							break;					
						}
						jsr_p = jsr_p->next;
					}
					strcat(machine_code,jsr_bin_2);				
				}
			}
			else
			{
				condition_code = "0100000";
				strcpy(machine_code,condition_code);
				count++;
				single = my_strtok(single[count],enter);
				char *jsrr_bin = reg_num(single[0]);
				strcat(machine_code,jsrr_bin);
				strcat(machine_code,jmp_bin_2);
			}
			break;
		}
		if(strcmp(single[count],str9) == 0 || strcmp(single[count],str10) == 0 || strcmp(single[count],str15) == 0 ||strcmp(single[count],str16) == 0)//LD or LDI or ST or STI
		{
			if(strcmp(single[count],str9) == 0)
			{
				condition_code = "0010";				
			}
			else if(strcmp(single[count],str10) == 0)
			{
				condition_code = "1010";
			}
			else if(strcmp(single[count],str15) == 0)
			{
				condition_code = "0011";
			}
			else
			{
				condition_code = "1011";
			}
			strcpy(machine_code,condition_code);
			count ++ ;
			char *ld_bin = reg_num(single[count]);
			strcat(machine_code,ld_bin);
			count ++ ;
			single = my_strtok(single[count],enter);
			if(single[0][0] == '#' || single[0][0] == 'x')
			{
				char *ld_num_bin  = bin_transfer(single[0],9);
				strcat(machine_code,ld_num_bin);
			}		
			else
			{
				Lable *ld_p = head;
				ld_p->name = (char *)malloc(100 *sizeof(char));
				char *ld_bin_2;
				while(ld_p != NULL)
				{
					if(strcmp(single[0],ld_p->name) == 0)
					{
						int ld_sub = ld_p->pos - 1 - line;
						ld_bin_2 = to_binary(ld_sub,9);
						break;						
					}
					ld_p = ld_p->next;
				}
				strcat(machine_code,ld_bin_2);				
			}	

			break;			
		}
		if(strcmp(single[count],str11) == 0 || strcmp(single[count],str17) == 0)//LDR or STR
		{
			if(strcmp(single[count],str11) == 0)
			{
				condition_code = "0110";
			}
			else
			{
				condition_code = "0111";
			}
			strcpy(machine_code,condition_code);
			count ++ ;
			char *ldr_bin_1 = reg_num(single[count]);
			strcat(machine_code,ldr_bin_1);
			count ++ ;
			char *ldr_bin_2 = reg_num(single[count]);
			strcat(machine_code,ldr_bin_2);
			count ++ ;
			single = my_strtok(single[count],enter);
			char *ldr_bin_3 = bin_transfer(single[0],6);
			strcat(machine_code,ldr_bin_3);
			break;
		}
		if(strcmp(single[count],str12) == 0)//LEA
		{
			condition_code = "1110";
			strcpy(machine_code,condition_code);
			count ++;
			char *lea_bin_1 = reg_num(single[count]);
			
			strcat(machine_code,lea_bin_1);
			count++;
			single = my_strtok(single[count],enter);
			if(single[0][0] == '#' || single[0][0] == 'x')
			{
				char *lea_num_bin  = bin_transfer(single[0],9);
				strcat(machine_code,lea_num_bin);
			}
			else
			{
				Lable *lea_p = head;
				lea_p->name = (char *)malloc(100 *sizeof(char));
				char *lea_bin_2;
				while(lea_p!= NULL)
				{
					if(strcmp(single[0],lea_p->name) == 0)
					{
						int lea_sub = lea_p->pos - 1 - line;
						lea_bin_2 = to_binary(lea_sub,9);
						break;						
					}
					lea_p = lea_p->next;
				}
				strcat(machine_code,lea_bin_2);					
			}	
			break;		
		}
		if(strcmp(single[count],str13) == 0)//NOT
		{
			condition_code = "1001";
			strcpy(machine_code,condition_code);
			count ++ ;
			char *not_bin_1 = reg_num(single[count]);
			strcat(machine_code,not_bin_1);
			count ++ ;
			single = my_strtok(single[count],enter);
			char *not_bin_2 = reg_num(single[0]);
			strcat(machine_code,not_bin_2);	
			char *not_bin_3 = "111111";
			strcat(machine_code,not_bin_3);	
			break;				
		}
		if(strcmp(single[count],str14) == 0)//RTI
		{
			condition_code= "1000000000000000";
			strcpy(machine_code,condition_code);
			break;
		}
		if(strcmp(single[count],str18) == 0)//.TRAP
		{
			condition_code = "11110000";
			strcpy(machine_code,condition_code);
			count++;
			single = my_strtok(single[count],enter);
			char *trap_bin = bin_transfer(single[0],8);
			strcat(machine_code,trap_bin);
			break;
		}
		if(strcmp(single[count],str19) == 0)//.BLKW
		{
			count++;
			int blkw_dec;
			if(single[count][0] == 'x')
			{
				char blkw_tem1 = 'x';
				single = my_strtok(single[count],blkw_tem1);
				blkw_dec = hexToDec(single[0]);
			}
			if(single[count][0] == '#')
			{
				char blkw_tem2 = '#';
				single = my_strtok(single[count],blkw_tem2);
				blkw_dec = strtol(single[0],NULL,10);
			}
			trans_line += blkw_dec - 1;
			char *blkw_bin_1 = "0000000000000000";
			char *blkw_bin_2 = "0000000000000000\n";
			if(blkw_dec == 1)
			{
				machine_code = "0000000000000000";
			}
			else
			{
				for(int bi = 0;bi<blkw_dec - 1;bi++)//表示存入多少行的16位的0
				{
					if(bi == 0)
					{
						condition_code = "0000000000000000\n"	;
						strcpy(machine_code,condition_code);
					}
					else
					{
						strcat(machine_code,blkw_bin_2);
					}
				}
				strcat(machine_code,blkw_bin_1);
			}
			break;			
		}
		if(strcmp(single[count],str20) == 0)//.STRINGZ
		{
			char ascii_bin[100] = {0};
			count++;
			char *space_1 = " ";
			while(single[count]!=NULL)
			{
				strcat(ascii_bin,single[count]);
				strcat(ascii_bin,space_1);
				count ++;
			}
			int trans_pos = strlen(ascii_bin) - 3;
			trans_line += trans_pos;//全局变量控制当前语句行数,只有BLKW和STRINGZ会改变
			single = my_strtok(ascii_bin,enter);
			int si = 1;
			char *enter_1 = "\n";//换行
			while(single[0][si]!='"' && single[0][si+1]!='\0')//把双引号内的字符串一个一个转换为ascii值对应的二进制数并存入
			{
				if(si == 1)
				{
					condition_code = word_ascii(single[0][si]);
					strcpy(machine_code,condition_code);
					strcat(machine_code,enter_1);
				}
				else if(single[0][si+1]!='"')
				{
					char *str_bin = word_ascii(single[0][si]);
					strcat(machine_code,str_bin);
					strcat(machine_code,enter_1);
				}
				else
				{
					char *str_bin_2 = word_ascii(single[0][si]);
					strcat(machine_code,str_bin_2);	
					char *zero = "0000000000000000";
					strcat(machine_code,enter_1);
					strcat(machine_code,zero);				
				}
				si++;
			}
			break;
		}
		if(strcmp(single[count],str22) == 0)//.END
		{
			machine_code = "\0";
			break;
		}		
	}
	return machine_code;
}

char *word_ascii(char word)//字母转换为ascii值并转换为16位二进制编码
{
	int ascii = (int)word;
	char *ascii_bin = to_binary(ascii,16);
	return ascii_bin;
}

Lable *get_lable_pos(char lines[][MAX_LINE_LENGTH],int line_index)
{
	    char *str[] = {".ORIG","ADD","AND","BR","BRN",
						"BRZ","BRP","BRNZ","BRNP","BRZP",
						"BRNZP","JMP","RET","JSR","JSRR",
						"LD","LDI","LDR","LEA","NOT","RTI",
						"ST","STI","STR","TRAP",".BLKW",
 						".STRINGZ",".FILL",".END"};
 	char **act_str;
 	Lable  *lable_head = (Lable*)malloc(sizeof(Lable)); //标签链表头结点
 	int j = 0;
 	int temp = 0;
 	int str_pos = 0;
	for(int k = 0 ;k<line_index;k++)
	{
		char *instroction = lines[k];
 		char space_lable = ' ';
 		char enter_lable = '\n';
 		char **act_str_son;
 		act_str = my_strtok(instroction,space_lable);
 		act_str_son = my_strtok(act_str[0],enter_lable);
		temp = 0;
		for(int j = 0;j<29;j++)
		{
			if(strcmp(act_str_son[0],str[j])!=0)
			{
				temp++;
			}
		}
		if(temp == 29)//当不是这29个指令时,记为标签,头插法创建标签链表
		{
			Lable *p = (Lable*)malloc(sizeof(Lable)); 
			p->name = (char*)malloc(100 * sizeof(char));
			strcpy(p->name,act_str_son[0]);
			p->pos = k + str_pos + 1;//记录标签位置
			p->next = lable_head ->next;
			lable_head->next = p;
			if(strcmp(act_str[1],str[26]) == 0)//STRINGZ进行更改
			{
				char str_len[100] = {0};
				char *space_2 = " ";
				int m = 2;
				while(act_str[m]!=NULL)
				{
					strcat(str_len,act_str[m]);
					strcat(str_len,space_2);
					m ++;
				}
				str_pos += strlen(str_len) - 4;//减4是两个双引号,多加的空格和最后的换行
			}
			if(strcmp(act_str[1],str[25]) == 0)//BLKW进行更改
			{
				char lable_tem = '#';
				act_str = my_strtok(act_str_son[2],lable_tem);
				int lable_dec = strtol(act_str[0],NULL,10);
				str_pos += lable_dec;
			}			
		}			
	}
	return lable_head;
}

char *reg_num(char *str)//检测寄存器模块,输出为寄存器对应二进制编码
{
		char reg1[] = "R0";
		char reg2[] = "R1";
		char reg3[] = "R2";
		char reg4[] = "R3";
		char reg5[] = "R4";
		char reg6[] = "R5";
		char reg7[] = "R6";
		char reg8[] = "R7";
		
		char tem = ',';
	char **reg_str;	
	reg_str = my_strtok(str,tem);//去逗号	
	char *bin = (char *)malloc(sizeof(char) * 3);
	if(strcmp(reg_str[0],reg1) == 0)
	{
		bin = "000";
	}
	if(strcmp(reg_str[0],reg2) == 0)
	{
		bin = "001";
	}
	if(strcmp(reg_str[0],reg3) == 0)
	{
		bin = "010";
	}
	if(strcmp(reg_str[0],reg4) == 0)
	{
		bin = "011";
	}
	if(strcmp(reg_str[0],reg5) == 0)
	{
		bin = "100";
	}
	if(strcmp(reg_str[0],reg6) == 0)
	{
		bin = "101";
	}
	if(strcmp(reg_str[0],reg7) == 0)
	{
		bin = "110";
	}
	if(strcmp(reg_str[0],reg8) == 0)
	{
		bin = "111";
	}
	return bin;
}

char **my_strtok(const char *source, char flag)
{
    char **pt;
    int j, n = 0;
    int count = 1;
    int len = strlen(source);
    // 动态分配一个 *tmp,静态的话,变量len无法用于下标
    char *tmp = (char*)malloc((len + 1) * sizeof(char));
    tmp[0] = '\0';

    for (int i = 0; i < len; ++i)
    {
        if (source[i] == flag && source[i+1] == '\0')
            continue;
        else if (source[i] == flag && source[i+1] != flag)
            count++;
    }
    // 多分配一个char*,是为了设置结束标志
    pt = (char**)malloc((count+1) * sizeof(char*));

    count = 0;
    for (int i = 0; i < len; ++i)
    {
        if (i == len - 1 && source[i] != flag)
        {
            tmp[n++] = source[i];
            tmp[n] = '\0';  // 字符串末尾添加空字符
            j = strlen(tmp) + 1;
            pt[count] = (char*)malloc(j * sizeof(char));
            strcpy(pt[count++], tmp);
        }
        else if (source[i] == flag)
        {
            j = strlen(tmp);
            if (j != 0)
            {
                tmp[n] = '\0';  // 字符串末尾添加空字符
                pt[count] = (char*)malloc((j+1) * sizeof(char));
                strcpy(pt[count++], tmp);
                // 重置tmp
                n = 0;
                tmp[0] = '\0';
            }
        }
        else
            tmp[n++] = source[i];
    }
	free(tmp);	
    // 设置结束标志
    pt[count] = NULL;
    return pt;
}

void reverse(char* left, char* right) //翻转数组
{
	while (left < right) {
		char tmp = *right;
		*right = *left;
		*left = tmp;
		left++;
		right--;
	}
}
char* to_binary(int n, int m)//假设要求m位二进制数
{
	char a[10000] = { '\0' };
	int i = 0;
	int n_2 = 0;
	if(n<0)//若是负数
	{
		n = abs(n);
		n_2 = pow(2,m-1);
		n = n_2 - n;//2的n-1次方减去绝对值得补码
		while (n != 0)
		{
			a[i++] = '0' + n % 2;
			n = n / 2;
		}
		reverse(a, a + strlen(a) - 1);
		char b[10000] = {'1'};
		for (int i = 1; i < m - strlen(a); i++)
		{
			b[i] = '0';
		}
		return strcat(b,a);
	}
	else
	{
		while (n != 0)
		{
			a[i++] = '0' + n % 2;
			n = n / 2;
		}
		reverse(a, a + strlen(a) - 1);			
		char b[10000] = {'\0'};		
		for (int i = 0; i < m - strlen(a); i++)
		{
			b[i] = '0';
		}
		return strcat(b,a);
	}
}

long hexToDec(char *source)//十六进制转十进制
{
    long sum = 0;
    long t = 1;
    int i, len;
 
    len = strlen(source);
    for(i=len-1; i>=0; i--)
    {
        sum += t * getIndexOfSigns(*(source + i));
        t *= 16;
    }  
 
    return sum;
}
 
int getIndexOfSigns(char ch)
{
    if(ch >= '0' && ch <= '9')
    {
        return ch - '0';
    }
    if(ch >= 'A' && ch <='F') 
    {
        return ch - 'A' + 10;
    }
    if(ch >= 'a' && ch <= 'f')
    {
        return ch - 'a' + 10;
    }
    return -1;
}

char *bin_transfer(char *str,int bit)//"xn" or "#n"转换为二进制编码字符串
{
	int dec;
	char *bin = (char *)malloc(sizeof(char) * 16);
	int index = 0;
	char **bin_str;
	if(str[0] == 'x')
	{
		char tem = 'x';
		bin_str = my_strtok(str,tem);
		dec = hexToDec(bin_str[0]);

	}
	if(str[0] == '#')
	{
		char tem = '#';
		bin_str = my_strtok(str,tem);
		dec = strtol(bin_str[0],NULL,10);
	}
	char *binary = to_binary(dec,bit);
	return binary;
}

1月25日更:

        注意,这个代码中的.STRINGZ实现的是把字符串存入后再把下一个内存空间置为x0000,即和标准功能一样,但如果最后一个.STRINGZ不需要这样做的话(即.END前面跟的是.STRINGZ,末尾没必要加x0000),需要修改代码,加一个全局变量来控制输出,如下所示:

int end_flag = 0;
void assemble(...)
{
    //...下面的内容放在for循环里
    char check_space = ' ';
    char check_enter = '\n';
    if(i!=num_lines-1)
    {
        char **check = my_strtok(lines[i],check_space);
        char **check_next = my_strtok(lines[i+1],check_enter);
        int k = 0;
        char check_str1[] = ".STRINGZ";
        char check_str2[] = ".END";
        while(check[k]!=NULL)
        {
            if(strcmp(check[k],check_str1) == 0)
            {
                if(strcmp(check_next[0],check_str2) == 0)
                {
                    end_flag = 1;
                }
                else
                {
                k++;
                }
            }
        }
    }
}
//同时修改translate函数中的.STRINGZ分支,只需判断end_flag即可
char * translate_instruction(...)
{
    //...
	else
	{
		char *str_bin_2 = word_ascii(single[0][si]);
		strcat(machine_code,str_bin_2);	
		char *zero = "0000000000000000";
		strcat(machine_code,enter_1);
        if(end_flag == 0)
        {        
			strcat(machine_code,zero);	
        }			
	}

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陌辞_Z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值