当前位置:   article > 正文

C语言实现简易LC-3汇编器_lc3汇编语言string指令

lc3汇编语言string指令

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

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <math.h>
  5. #define MAX_LINE_LENGTH 100
  6. //标签链表结构体,用于储存标签名以及标签位置
  7. typedef struct Lable{
  8. char * name;
  9. int pos;
  10. struct Lable *next;
  11. }Lable;
  12. // Function prototypes
  13. void read_asm_file(const char *filename, char lines[][MAX_LINE_LENGTH], int *num_lines);
  14. void write_output_file(const char *filename, const char *output[], int num_lines);
  15. void assemble(char lines[][MAX_LINE_LENGTH], int num_lines, char *output[]);
  16. char * translate_instruction(char *instruction,int line,Lable *head);
  17. char *bin_transfer(char *str,int bit);
  18. char *reg_num(char *str);
  19. Lable *get_lable_pos(char lines[][MAX_LINE_LENGTH],int line_index);
  20. char *word_ascii(char word);
  21. char **my_strtok(const char *source, char flag);
  22. int getIndexOfSigns(char ch);
  23. long hexToDec(char *source);
  24. void reverse(char* left, char* right);
  25. char* to_binary(int n, int m);
  26. // TODO: Define any additional functions you need to implement the assembler, e.g. the symbol table.
  27. int main(int argc, char *argv[])
  28. //int main()
  29. {
  30. // Command-line argument parsing
  31. if (argc != 3)
  32. {
  33. fprintf(stderr, "Usage: %s <input_file.asm> <output_file.txt>\n", argv[0]);
  34. return 1;
  35. }
  36. char input_filename[100];
  37. char output_filename[100];
  38. strcpy(input_filename, argv[1]);
  39. strcpy(output_filename, argv[2]);
  40. // printf("input input_filename:\n");
  41. // scanf("%s",&input_filename);
  42. // printf("input output_filename:\n");
  43. // scanf("%s",&output_filename);
  44. char lines[100][MAX_LINE_LENGTH]; // Assuming a maximum of 100 lines
  45. int num_lines = 0;
  46. read_asm_file(input_filename, lines, &num_lines);
  47. char *output[100]; // Output array of strings
  48. for (int i = 0; i < 100; i++)
  49. {
  50. output[i] = (char *)malloc(MAX_LINE_LENGTH * sizeof(char));
  51. }
  52. assemble(lines, num_lines, output);
  53. write_output_file(output_filename, (const char **)output, num_lines);
  54. // Free allocated memory
  55. for (int i = 0; i < 100; i++)
  56. {
  57. free(output[i]);
  58. }
  59. return 0;
  60. }
  61. void read_asm_file(const char *filename, char lines[][MAX_LINE_LENGTH], int *num_lines)
  62. {
  63. FILE *file = fopen(filename, "r");
  64. if (file == NULL)
  65. {
  66. fprintf(stderr, "Unable to open file: %s\n", filename);
  67. exit(1);
  68. }
  69. char line[MAX_LINE_LENGTH];
  70. while (fgets(line, MAX_LINE_LENGTH, file))
  71. {
  72. strcpy(lines[*num_lines], line);
  73. printf("%s",lines[*num_lines]);
  74. (*num_lines)++;
  75. }
  76. fclose(file);
  77. }
  78. void write_output_file(const char *filename, const char *output[], int num_lines)
  79. {
  80. FILE *file = fopen(filename, "w");
  81. if (file == NULL)
  82. {
  83. fprintf(stderr, "Unable to open file: %s\n", filename);
  84. exit(1);
  85. }
  86. for (int i = 0; i < num_lines; i++)
  87. {
  88. fprintf(file, "%s\n", output[i]);
  89. }
  90. fclose(file);
  91. }
  92. int trans_line = 1;
  93. void assemble(char lines[][MAX_LINE_LENGTH], int num_lines, char *output[])
  94. {
  95. // TODO: Implement the assembly process
  96. // Implement the 2-pass process described in textbook.
  97. Lable *lable;
  98. lable = get_lable_pos(lines,num_lines);//第一次遍历创建标签链表
  99. char *tem_output;
  100. for (int i = 0; i < num_lines; i++)
  101. {
  102. tem_output = translate_instruction(lines[i],i+trans_line,lable);//临时指针存转码结果
  103. strcpy(output[i],tem_output);
  104. printf("\n%s",output[i]);//打印结果
  105. }
  106. }
  107. char * translate_instruction(char *instruction,int line,Lable *head)
  108. {
  109. char *machine_code;//要返回的机器码
  110. machine_code = (char *)malloc(MAX_LINE_LENGTH * sizeof(char));//分配空间
  111. char *condition_code;//条件码
  112. //下面是用到的29个指令
  113. char str1[] = ".ORIG";
  114. char str2[] = "ADD";
  115. char str3[] = "AND";
  116. char str4[] = "BR";
  117. char str4_1[] = "BRN";
  118. char str4_2[] = "BRZ";
  119. char str4_3[] = "BRP";
  120. char str4_4[] = "BRNZ";
  121. char str4_5[] = "BRNP";
  122. char str4_6[] = "BRZP";
  123. char str4_7[] = "BRNZP";//BR子指令
  124. char str5[] = "JMP";
  125. char str6[] = "RET";
  126. char str7[] = "JSR";
  127. char str8[] = "JSRR";
  128. char str9[] = "LD";
  129. char str10[] = "LDI";
  130. char str11[] = "LDR";
  131. char str12[] = "LEA";
  132. char str13[] = "NOT";
  133. char str14[] = "RTI";
  134. char str15[] = "ST";
  135. char str16[] = "STI";
  136. char str17[] = "STR";
  137. char str18[] = "TRAP";
  138. char str19[] = ".BLKW";
  139. char str20[] = ".STRINGZ";
  140. char str21[] = ".FILL";
  141. char str22[] = ".END";
  142. char ** single ;//用来存分割后的字符串
  143. char space = ' ';//按空格分割
  144. char enter = '\n';//按换行分割,因为字符串最后有\n
  145. char *reg_number = "000";
  146. char *imm_number = "1";//一些机器码中用到的码
  147. single = my_strtok(instruction,enter);
  148. single = my_strtok(single[0],space);//第一次分割,得到各个子字符串
  149. int bin_num;
  150. int count;//计数,表示是分割后的第几个字符串
  151. for(count = 0;;count++)
  152. {
  153. if(strcmp(single[count],str1) == 0 || strcmp(single[count],str21) == 0)//.ORIG or .FILL
  154. {
  155. single = my_strtok(single[count+1],enter);//去换行操作
  156. machine_code= bin_transfer(single[0],16);//将语句后面带的数直接转为16位二进制编码
  157. break;
  158. }
  159. if(strcmp(single[count],str2) == 0 || strcmp(single[count],str3) == 0)//ADD or AND
  160. {
  161. if(strcmp(single[count],str2) == 0)
  162. {
  163. condition_code = "0001";
  164. }
  165. else
  166. {
  167. condition_code = "0101";//先存入指令码,后面类似
  168. }
  169. strcpy(machine_code,condition_code);
  170. count ++;
  171. if(single[count][0] != '#' && single[count][0] != 'x')//这句并没有多大用处,因为ADD或AND后面两个都是寄存器
  172. {
  173. char *ad_binary_1 = reg_num(single[count++]);//判断寄存器
  174. strcat(machine_code,ad_binary_1);
  175. }
  176. if(single[count][0] != '#' && single[count][0] != 'x')
  177. {
  178. char *ad_binary_2 = reg_num(single[count++]);
  179. strcat(machine_code,ad_binary_2);
  180. }
  181. single = my_strtok(single[count],enter);
  182. if(single[0][0] != '#' && single[0][0] != 'x')//检测是立即数还是寄存器
  183. {
  184. strcat(machine_code,reg_number);
  185. char *ad_binary_3 = reg_num(single[0]);
  186. strcat(machine_code,ad_binary_3);
  187. }
  188. else
  189. {
  190. strcat(machine_code,imm_number);
  191. char *ad_bin;
  192. ad_bin = bin_transfer(single[0],5);
  193. strcat(machine_code,ad_bin);
  194. }
  195. break;
  196. }
  197. 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)
  198. {
  199. if(strcmp(single[count],str4) == 0 || strcmp(single[count],str4_7) == 0)//BR or BRNZP
  200. {
  201. condition_code = "0000111";
  202. }
  203. if(strcmp(single[count],str4_1) == 0)//BRN
  204. {
  205. condition_code = "0000100";
  206. }
  207. if(strcmp(single[count],str4_2) == 0)//BRZ
  208. {
  209. condition_code = "0000010";
  210. }
  211. if(strcmp(single[count],str4_3) == 0)//BRP
  212. {
  213. condition_code = "0000001";
  214. }
  215. if(strcmp(single[count],str4_4) == 0)//BRNZ
  216. {
  217. condition_code = "0000110";
  218. }
  219. if(strcmp(single[count],str4_5) == 0)//BRNP
  220. {
  221. condition_code = "0000101";
  222. }
  223. if(strcmp(single[count],str4_6) == 0)//BRZP
  224. {
  225. condition_code = "0000011";
  226. }
  227. strcpy(machine_code,condition_code);
  228. count++;
  229. single = my_strtok(single[count],enter);
  230. if(single[0][0] == '#' || single[0][0] == 'x')//检测是立即数还是标签
  231. {
  232. char *br_bin = bin_transfer(single[0],9);
  233. strcat(machine_code,br_bin);
  234. }
  235. else
  236. {
  237. Lable *p = head;
  238. char *br_bin_2;
  239. char *imm_0 = "000000000";
  240. while(p!= NULL)//遍历标签链表找到对应标签所在位置(行数)
  241. {
  242. if(strcmp(single[0],p->name) == 0)
  243. {
  244. int sub = p->pos - 1 - line;//标签行数减PC增量减当前行数
  245. if(sub == 0)
  246. {
  247. strcat(machine_code,imm_0);
  248. break;
  249. }
  250. else
  251. {
  252. br_bin_2 = to_binary(sub,9); //得到差值并转为9位二进制编码
  253. strcat(machine_code,br_bin_2);
  254. break;
  255. }
  256. }
  257. p = p->next;
  258. }
  259. }
  260. break;
  261. }
  262. char *jmp_bin_2 = "000000";
  263. if(strcmp(single[count],str5) == 0 || strcmp(single[count],str6) == 0)//JMP or RET
  264. {
  265. if(strcmp(single[count],str5) == 0)
  266. {
  267. condition_code = "1100000";
  268. strcpy(machine_code,condition_code);
  269. count ++ ;
  270. single = my_strtok(single[count],enter);
  271. char *jmp_bin = reg_num(single[0]);
  272. strcat(machine_code,jmp_bin);
  273. strcat(machine_code,jmp_bin_2);
  274. }
  275. else
  276. {
  277. condition_code = "1100000111000000";
  278. strcpy(machine_code,condition_code);
  279. }
  280. break;
  281. }
  282. if(strcmp(single[count],str7) == 0 || strcmp(single[count],str8) == 0)//JSR or JSRR
  283. {
  284. if(strcmp(single[count],str7) == 0)
  285. {
  286. condition_code = "01001";
  287. strcpy(machine_code,condition_code);
  288. count ++ ;
  289. single = my_strtok(single[count],enter);
  290. if(single[0][0] == '#' || single[0][0] == 'x')
  291. {
  292. char *jsr_num_bin = bin_transfer(single[0],11);
  293. strcat(machine_code,jsr_num_bin);
  294. }
  295. else
  296. {
  297. Lable *jsr_p = head;//同样的检测标签并返回,只不过变为了11位
  298. jsr_p->name = (char *)malloc(100 *sizeof(char));
  299. char *jsr_bin_2;
  300. while(jsr_p != NULL)
  301. {
  302. if(strcmp(single[0],jsr_p->name) == 0)
  303. {
  304. int jsr_sub = jsr_p->pos - 1 - line ;
  305. jsr_bin_2 = to_binary(jsr_sub,11);
  306. break;
  307. }
  308. jsr_p = jsr_p->next;
  309. }
  310. strcat(machine_code,jsr_bin_2);
  311. }
  312. }
  313. else
  314. {
  315. condition_code = "0100000";
  316. strcpy(machine_code,condition_code);
  317. count++;
  318. single = my_strtok(single[count],enter);
  319. char *jsrr_bin = reg_num(single[0]);
  320. strcat(machine_code,jsrr_bin);
  321. strcat(machine_code,jmp_bin_2);
  322. }
  323. break;
  324. }
  325. 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
  326. {
  327. if(strcmp(single[count],str9) == 0)
  328. {
  329. condition_code = "0010";
  330. }
  331. else if(strcmp(single[count],str10) == 0)
  332. {
  333. condition_code = "1010";
  334. }
  335. else if(strcmp(single[count],str15) == 0)
  336. {
  337. condition_code = "0011";
  338. }
  339. else
  340. {
  341. condition_code = "1011";
  342. }
  343. strcpy(machine_code,condition_code);
  344. count ++ ;
  345. char *ld_bin = reg_num(single[count]);
  346. strcat(machine_code,ld_bin);
  347. count ++ ;
  348. single = my_strtok(single[count],enter);
  349. if(single[0][0] == '#' || single[0][0] == 'x')
  350. {
  351. char *ld_num_bin = bin_transfer(single[0],9);
  352. strcat(machine_code,ld_num_bin);
  353. }
  354. else
  355. {
  356. Lable *ld_p = head;
  357. ld_p->name = (char *)malloc(100 *sizeof(char));
  358. char *ld_bin_2;
  359. while(ld_p != NULL)
  360. {
  361. if(strcmp(single[0],ld_p->name) == 0)
  362. {
  363. int ld_sub = ld_p->pos - 1 - line;
  364. ld_bin_2 = to_binary(ld_sub,9);
  365. break;
  366. }
  367. ld_p = ld_p->next;
  368. }
  369. strcat(machine_code,ld_bin_2);
  370. }
  371. break;
  372. }
  373. if(strcmp(single[count],str11) == 0 || strcmp(single[count],str17) == 0)//LDR or STR
  374. {
  375. if(strcmp(single[count],str11) == 0)
  376. {
  377. condition_code = "0110";
  378. }
  379. else
  380. {
  381. condition_code = "0111";
  382. }
  383. strcpy(machine_code,condition_code);
  384. count ++ ;
  385. char *ldr_bin_1 = reg_num(single[count]);
  386. strcat(machine_code,ldr_bin_1);
  387. count ++ ;
  388. char *ldr_bin_2 = reg_num(single[count]);
  389. strcat(machine_code,ldr_bin_2);
  390. count ++ ;
  391. single = my_strtok(single[count],enter);
  392. char *ldr_bin_3 = bin_transfer(single[0],6);
  393. strcat(machine_code,ldr_bin_3);
  394. break;
  395. }
  396. if(strcmp(single[count],str12) == 0)//LEA
  397. {
  398. condition_code = "1110";
  399. strcpy(machine_code,condition_code);
  400. count ++;
  401. char *lea_bin_1 = reg_num(single[count]);
  402. strcat(machine_code,lea_bin_1);
  403. count++;
  404. single = my_strtok(single[count],enter);
  405. if(single[0][0] == '#' || single[0][0] == 'x')
  406. {
  407. char *lea_num_bin = bin_transfer(single[0],9);
  408. strcat(machine_code,lea_num_bin);
  409. }
  410. else
  411. {
  412. Lable *lea_p = head;
  413. lea_p->name = (char *)malloc(100 *sizeof(char));
  414. char *lea_bin_2;
  415. while(lea_p!= NULL)
  416. {
  417. if(strcmp(single[0],lea_p->name) == 0)
  418. {
  419. int lea_sub = lea_p->pos - 1 - line;
  420. lea_bin_2 = to_binary(lea_sub,9);
  421. break;
  422. }
  423. lea_p = lea_p->next;
  424. }
  425. strcat(machine_code,lea_bin_2);
  426. }
  427. break;
  428. }
  429. if(strcmp(single[count],str13) == 0)//NOT
  430. {
  431. condition_code = "1001";
  432. strcpy(machine_code,condition_code);
  433. count ++ ;
  434. char *not_bin_1 = reg_num(single[count]);
  435. strcat(machine_code,not_bin_1);
  436. count ++ ;
  437. single = my_strtok(single[count],enter);
  438. char *not_bin_2 = reg_num(single[0]);
  439. strcat(machine_code,not_bin_2);
  440. char *not_bin_3 = "111111";
  441. strcat(machine_code,not_bin_3);
  442. break;
  443. }
  444. if(strcmp(single[count],str14) == 0)//RTI
  445. {
  446. condition_code= "1000000000000000";
  447. strcpy(machine_code,condition_code);
  448. break;
  449. }
  450. if(strcmp(single[count],str18) == 0)//.TRAP
  451. {
  452. condition_code = "11110000";
  453. strcpy(machine_code,condition_code);
  454. count++;
  455. single = my_strtok(single[count],enter);
  456. char *trap_bin = bin_transfer(single[0],8);
  457. strcat(machine_code,trap_bin);
  458. break;
  459. }
  460. if(strcmp(single[count],str19) == 0)//.BLKW
  461. {
  462. count++;
  463. int blkw_dec;
  464. if(single[count][0] == 'x')
  465. {
  466. char blkw_tem1 = 'x';
  467. single = my_strtok(single[count],blkw_tem1);
  468. blkw_dec = hexToDec(single[0]);
  469. }
  470. if(single[count][0] == '#')
  471. {
  472. char blkw_tem2 = '#';
  473. single = my_strtok(single[count],blkw_tem2);
  474. blkw_dec = strtol(single[0],NULL,10);
  475. }
  476. trans_line += blkw_dec - 1;
  477. char *blkw_bin_1 = "0000000000000000";
  478. char *blkw_bin_2 = "0000000000000000\n";
  479. if(blkw_dec == 1)
  480. {
  481. machine_code = "0000000000000000";
  482. }
  483. else
  484. {
  485. for(int bi = 0;bi<blkw_dec - 1;bi++)//表示存入多少行的16位的0
  486. {
  487. if(bi == 0)
  488. {
  489. condition_code = "0000000000000000\n" ;
  490. strcpy(machine_code,condition_code);
  491. }
  492. else
  493. {
  494. strcat(machine_code,blkw_bin_2);
  495. }
  496. }
  497. strcat(machine_code,blkw_bin_1);
  498. }
  499. break;
  500. }
  501. if(strcmp(single[count],str20) == 0)//.STRINGZ
  502. {
  503. char ascii_bin[100] = {0};
  504. count++;
  505. char *space_1 = " ";
  506. while(single[count]!=NULL)
  507. {
  508. strcat(ascii_bin,single[count]);
  509. strcat(ascii_bin,space_1);
  510. count ++;
  511. }
  512. int trans_pos = strlen(ascii_bin) - 3;
  513. trans_line += trans_pos;//全局变量控制当前语句行数,只有BLKW和STRINGZ会改变
  514. single = my_strtok(ascii_bin,enter);
  515. int si = 1;
  516. char *enter_1 = "\n";//换行
  517. while(single[0][si]!='"' && single[0][si+1]!='\0')//把双引号内的字符串一个一个转换为ascii值对应的二进制数并存入
  518. {
  519. if(si == 1)
  520. {
  521. condition_code = word_ascii(single[0][si]);
  522. strcpy(machine_code,condition_code);
  523. strcat(machine_code,enter_1);
  524. }
  525. else if(single[0][si+1]!='"')
  526. {
  527. char *str_bin = word_ascii(single[0][si]);
  528. strcat(machine_code,str_bin);
  529. strcat(machine_code,enter_1);
  530. }
  531. else
  532. {
  533. char *str_bin_2 = word_ascii(single[0][si]);
  534. strcat(machine_code,str_bin_2);
  535. char *zero = "0000000000000000";
  536. strcat(machine_code,enter_1);
  537. strcat(machine_code,zero);
  538. }
  539. si++;
  540. }
  541. break;
  542. }
  543. if(strcmp(single[count],str22) == 0)//.END
  544. {
  545. machine_code = "\0";
  546. break;
  547. }
  548. }
  549. return machine_code;
  550. }
  551. char *word_ascii(char word)//字母转换为ascii值并转换为16位二进制编码
  552. {
  553. int ascii = (int)word;
  554. char *ascii_bin = to_binary(ascii,16);
  555. return ascii_bin;
  556. }
  557. Lable *get_lable_pos(char lines[][MAX_LINE_LENGTH],int line_index)
  558. {
  559. char *str[] = {".ORIG","ADD","AND","BR","BRN",
  560. "BRZ","BRP","BRNZ","BRNP","BRZP",
  561. "BRNZP","JMP","RET","JSR","JSRR",
  562. "LD","LDI","LDR","LEA","NOT","RTI",
  563. "ST","STI","STR","TRAP",".BLKW",
  564. ".STRINGZ",".FILL",".END"};
  565. char **act_str;
  566. Lable *lable_head = (Lable*)malloc(sizeof(Lable)); //标签链表头结点
  567. int j = 0;
  568. int temp = 0;
  569. int str_pos = 0;
  570. for(int k = 0 ;k<line_index;k++)
  571. {
  572. char *instroction = lines[k];
  573. char space_lable = ' ';
  574. char enter_lable = '\n';
  575. char **act_str_son;
  576. act_str = my_strtok(instroction,space_lable);
  577. act_str_son = my_strtok(act_str[0],enter_lable);
  578. temp = 0;
  579. for(int j = 0;j<29;j++)
  580. {
  581. if(strcmp(act_str_son[0],str[j])!=0)
  582. {
  583. temp++;
  584. }
  585. }
  586. if(temp == 29)//当不是这29个指令时,记为标签,头插法创建标签链表
  587. {
  588. Lable *p = (Lable*)malloc(sizeof(Lable));
  589. p->name = (char*)malloc(100 * sizeof(char));
  590. strcpy(p->name,act_str_son[0]);
  591. p->pos = k + str_pos + 1;//记录标签位置
  592. p->next = lable_head ->next;
  593. lable_head->next = p;
  594. if(strcmp(act_str[1],str[26]) == 0)//STRINGZ进行更改
  595. {
  596. char str_len[100] = {0};
  597. char *space_2 = " ";
  598. int m = 2;
  599. while(act_str[m]!=NULL)
  600. {
  601. strcat(str_len,act_str[m]);
  602. strcat(str_len,space_2);
  603. m ++;
  604. }
  605. str_pos += strlen(str_len) - 4;//减4是两个双引号,多加的空格和最后的换行
  606. }
  607. if(strcmp(act_str[1],str[25]) == 0)//BLKW进行更改
  608. {
  609. char lable_tem = '#';
  610. act_str = my_strtok(act_str_son[2],lable_tem);
  611. int lable_dec = strtol(act_str[0],NULL,10);
  612. str_pos += lable_dec;
  613. }
  614. }
  615. }
  616. return lable_head;
  617. }
  618. char *reg_num(char *str)//检测寄存器模块,输出为寄存器对应二进制编码
  619. {
  620. char reg1[] = "R0";
  621. char reg2[] = "R1";
  622. char reg3[] = "R2";
  623. char reg4[] = "R3";
  624. char reg5[] = "R4";
  625. char reg6[] = "R5";
  626. char reg7[] = "R6";
  627. char reg8[] = "R7";
  628. char tem = ',';
  629. char **reg_str;
  630. reg_str = my_strtok(str,tem);//去逗号
  631. char *bin = (char *)malloc(sizeof(char) * 3);
  632. if(strcmp(reg_str[0],reg1) == 0)
  633. {
  634. bin = "000";
  635. }
  636. if(strcmp(reg_str[0],reg2) == 0)
  637. {
  638. bin = "001";
  639. }
  640. if(strcmp(reg_str[0],reg3) == 0)
  641. {
  642. bin = "010";
  643. }
  644. if(strcmp(reg_str[0],reg4) == 0)
  645. {
  646. bin = "011";
  647. }
  648. if(strcmp(reg_str[0],reg5) == 0)
  649. {
  650. bin = "100";
  651. }
  652. if(strcmp(reg_str[0],reg6) == 0)
  653. {
  654. bin = "101";
  655. }
  656. if(strcmp(reg_str[0],reg7) == 0)
  657. {
  658. bin = "110";
  659. }
  660. if(strcmp(reg_str[0],reg8) == 0)
  661. {
  662. bin = "111";
  663. }
  664. return bin;
  665. }
  666. char **my_strtok(const char *source, char flag)
  667. {
  668. char **pt;
  669. int j, n = 0;
  670. int count = 1;
  671. int len = strlen(source);
  672. // 动态分配一个 *tmp,静态的话,变量len无法用于下标
  673. char *tmp = (char*)malloc((len + 1) * sizeof(char));
  674. tmp[0] = '\0';
  675. for (int i = 0; i < len; ++i)
  676. {
  677. if (source[i] == flag && source[i+1] == '\0')
  678. continue;
  679. else if (source[i] == flag && source[i+1] != flag)
  680. count++;
  681. }
  682. // 多分配一个char*,是为了设置结束标志
  683. pt = (char**)malloc((count+1) * sizeof(char*));
  684. count = 0;
  685. for (int i = 0; i < len; ++i)
  686. {
  687. if (i == len - 1 && source[i] != flag)
  688. {
  689. tmp[n++] = source[i];
  690. tmp[n] = '\0'; // 字符串末尾添加空字符
  691. j = strlen(tmp) + 1;
  692. pt[count] = (char*)malloc(j * sizeof(char));
  693. strcpy(pt[count++], tmp);
  694. }
  695. else if (source[i] == flag)
  696. {
  697. j = strlen(tmp);
  698. if (j != 0)
  699. {
  700. tmp[n] = '\0'; // 字符串末尾添加空字符
  701. pt[count] = (char*)malloc((j+1) * sizeof(char));
  702. strcpy(pt[count++], tmp);
  703. // 重置tmp
  704. n = 0;
  705. tmp[0] = '\0';
  706. }
  707. }
  708. else
  709. tmp[n++] = source[i];
  710. }
  711. free(tmp);
  712. // 设置结束标志
  713. pt[count] = NULL;
  714. return pt;
  715. }
  716. void reverse(char* left, char* right) //翻转数组
  717. {
  718. while (left < right) {
  719. char tmp = *right;
  720. *right = *left;
  721. *left = tmp;
  722. left++;
  723. right--;
  724. }
  725. }
  726. char* to_binary(int n, int m)//假设要求m位二进制数
  727. {
  728. char a[10000] = { '\0' };
  729. int i = 0;
  730. int n_2 = 0;
  731. if(n<0)//若是负数
  732. {
  733. n = abs(n);
  734. n_2 = pow(2,m-1);
  735. n = n_2 - n;//2的n-1次方减去绝对值得补码
  736. while (n != 0)
  737. {
  738. a[i++] = '0' + n % 2;
  739. n = n / 2;
  740. }
  741. reverse(a, a + strlen(a) - 1);
  742. char b[10000] = {'1'};
  743. for (int i = 1; i < m - strlen(a); i++)
  744. {
  745. b[i] = '0';
  746. }
  747. return strcat(b,a);
  748. }
  749. else
  750. {
  751. while (n != 0)
  752. {
  753. a[i++] = '0' + n % 2;
  754. n = n / 2;
  755. }
  756. reverse(a, a + strlen(a) - 1);
  757. char b[10000] = {'\0'};
  758. for (int i = 0; i < m - strlen(a); i++)
  759. {
  760. b[i] = '0';
  761. }
  762. return strcat(b,a);
  763. }
  764. }
  765. long hexToDec(char *source)//十六进制转十进制
  766. {
  767. long sum = 0;
  768. long t = 1;
  769. int i, len;
  770. len = strlen(source);
  771. for(i=len-1; i>=0; i--)
  772. {
  773. sum += t * getIndexOfSigns(*(source + i));
  774. t *= 16;
  775. }
  776. return sum;
  777. }
  778. int getIndexOfSigns(char ch)
  779. {
  780. if(ch >= '0' && ch <= '9')
  781. {
  782. return ch - '0';
  783. }
  784. if(ch >= 'A' && ch <='F')
  785. {
  786. return ch - 'A' + 10;
  787. }
  788. if(ch >= 'a' && ch <= 'f')
  789. {
  790. return ch - 'a' + 10;
  791. }
  792. return -1;
  793. }
  794. char *bin_transfer(char *str,int bit)//"xn" or "#n"转换为二进制编码字符串
  795. {
  796. int dec;
  797. char *bin = (char *)malloc(sizeof(char) * 16);
  798. int index = 0;
  799. char **bin_str;
  800. if(str[0] == 'x')
  801. {
  802. char tem = 'x';
  803. bin_str = my_strtok(str,tem);
  804. dec = hexToDec(bin_str[0]);
  805. }
  806. if(str[0] == '#')
  807. {
  808. char tem = '#';
  809. bin_str = my_strtok(str,tem);
  810. dec = strtol(bin_str[0],NULL,10);
  811. }
  812. char *binary = to_binary(dec,bit);
  813. return binary;
  814. }

1月25日更:

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

  1. int end_flag = 0;
  2. void assemble(...)
  3. {
  4. //...下面的内容放在for循环里
  5. char check_space = ' ';
  6. char check_enter = '\n';
  7. if(i!=num_lines-1)
  8. {
  9. char **check = my_strtok(lines[i],check_space);
  10. char **check_next = my_strtok(lines[i+1],check_enter);
  11. int k = 0;
  12. char check_str1[] = ".STRINGZ";
  13. char check_str2[] = ".END";
  14. while(check[k]!=NULL)
  15. {
  16. if(strcmp(check[k],check_str1) == 0)
  17. {
  18. if(strcmp(check_next[0],check_str2) == 0)
  19. {
  20. end_flag = 1;
  21. }
  22. else
  23. {
  24. k++;
  25. }
  26. }
  27. }
  28. }
  29. }
  30. //同时修改translate函数中的.STRINGZ分支,只需判断end_flag即可
  31. char * translate_instruction(...)
  32. {
  33. //...
  34. else
  35. {
  36. char *str_bin_2 = word_ascii(single[0][si]);
  37. strcat(machine_code,str_bin_2);
  38. char *zero = "0000000000000000";
  39. strcat(machine_code,enter_1);
  40. if(end_flag == 0)
  41. {
  42. strcat(machine_code,zero);
  43. }
  44. }

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号