Advertisement
Guest User

Untitled

a guest
Mar 25th, 2017
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.08 KB | None | 0 0
  1. // to compile, gcc assembler.c -o assembler
  2. // No error check is provided.
  3. // Variable names cannot start with 0-9.
  4. // hexadecimals are twos complement.
  5. // first address of the code section is zero, data section follows the code section.
  6. //fout tables are formed: jump table, ldi table, label table and variable table.
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11.  
  12.  
  13. //Converts a hexadecimal string to integer.
  14. int hex2int( char* hex)
  15. {
  16. int result=0;
  17.  
  18. while ((*hex)!='\0')
  19. {
  20. if (('0'<=(*hex))&&((*hex)<='9'))
  21. result = result*16 + (*hex) -'0';
  22. else if (('a'<=(*hex))&&((*hex)<='f'))
  23. result = result*16 + (*hex) -'a'+10;
  24. else if (('A'<=(*hex))&&((*hex)<='F'))
  25. result = result*16 + (*hex) -'A'+10;
  26. hex++;
  27. }
  28. return(result);
  29. }
  30.  
  31.  
  32. main()
  33. {
  34. FILE *fp;
  35. char line[100];
  36. char *token = NULL;
  37. char *op1, *op2, *op3, *label;
  38. char ch;
  39. int chch;
  40.  
  41. int program[1000];
  42. int counter=0; //holds the address of the machine code instruction
  43.  
  44.  
  45.  
  46.  
  47. // A label is a symbol which mark a location in a program. In the example
  48. // program above, the string "lpp", "loop" and "lp1" are labels.
  49. struct label
  50. {
  51. int location;
  52. char *label;
  53. };
  54. struct label labeltable[50]; //there can be 50 labels at most in our programs
  55. int nooflabels = 0; //number of labels encountered during assembly.
  56.  
  57.  
  58.  
  59.  
  60. // Jump instructions cannot be assembled readily because we may not know the value of
  61. // the label when we encountered a jump instruction. This happens if the label used by
  62. // that jump instruction appear below that jump instruction. This is the situation
  63. // with the label "loop" in the example program above. Hence, the location of jump
  64. // instructions must be stored.
  65. struct jumpinstruction
  66. {
  67. int location;
  68. char *label;
  69. };
  70. struct jumpinstruction jumptable[100]; //There can be at most 100 jumps
  71. int noofjumps=0; //number of jumps encountered during assembly.
  72.  
  73.  
  74.  
  75.  
  76. // The list of variables in .data section and their locations.
  77. struct variable
  78. {
  79. int location;
  80. char *name;
  81. };
  82. struct variable variabletable[50]; //There can be 50 varables at most.
  83. int noofvariables = 0;
  84.  
  85.  
  86.  
  87.  
  88. //Variables and labels are used by ldi instructions.
  89. //The memory for the variables are traditionally allocated at the end of the code section.
  90. //Hence their addresses are not known when we assemble a ldi instruction. Also, the value of
  91. //a label may not be known when we encounter a ldi instruction which uses that label.
  92. //Hence, the location of the ldi instructions must be kept, and these instructions must be
  93. //modified when we discover the address of the label or variable that it uses.
  94. struct ldiinstruction
  95. {
  96. int location;
  97. char *name;
  98. };
  99. struct ldiinstruction lditable[100];
  100. int noofldis=0;
  101.  
  102.  
  103.  
  104.  
  105. fp = fopen("name_of_program","r");
  106.  
  107. if (fp != NULL)
  108. {
  109. while(fgets(line,sizeof line,fp)!= NULL) //skip till .code section
  110. {
  111. token=strtok(line,"\n\t\r ");
  112. if (strcmp(token,".code")==0 )
  113. break;
  114. }
  115. while(fgets(line,sizeof line,fp)!= NULL)
  116. {
  117. token=strtok(line,"\n\t\r "); //get the instruction mnemonic or label
  118.  
  119. //======================================== FIRST PASS ======================================================
  120. while (token)
  121. {
  122. if (strcmp(token,"ldi")==0) //---------------LDI INSTRUCTION--------------------
  123. {
  124. op1 = strtok(NULL,"\n\t\r "); //get the 1st operand of ldi, which is the register that ldi loads
  125. op2 = strtok(NULL,"\n\t\r "); //get the 2nd operand of ldi, which is the data that is to be loaded
  126. program[counter]=0x1000+hex2int(op1); //generate the first 16-bit of the ldi instruction
  127. counter++; //move to the second 16-bit of the ldi instruction
  128. if ((op2[0]=='0')&&(op2[1]=='x')) //if the 2nd operand is twos complement hexadecimal
  129. program[counter]=hex2int(op2+2)&0xffff; //convert it to integer and form the second 16-bit
  130. else if (( (op2[0])=='-') || ((op2[0]>='0')&&(op2[0]<='9'))) //if the 2nd operand is decimal
  131. program[counter]=atoi(op2)&0xffff; //convert it to integer and form the second 16-bit
  132. else //if the second operand is not decimal or hexadecimal, it is a laber or a variable.
  133. { //in this case, the 2nd 16-bits of the ldi instruction cannot be generated.
  134. lditable[noofldis].location = counter; //record the location of this 2nd 16-bit
  135. op1=(char*)malloc(sizeof(op2)); //and the name of the label/variable that it must contain
  136. strcpy(op1,op2); //in the lditable array.
  137. lditable[noofldis].name = op1;
  138. noofldis++;
  139. }
  140. counter++; //skip to the next memory location
  141. }
  142.  
  143. else if (strcmp(token,"ld")==0) //------------LD INSTRUCTION---------------------
  144. {
  145. op1 = strtok(NULL,"\n\t\r "); //get the 1st operand of ld, which is the destination register
  146. op2 = strtok(NULL,"\n\t\r "); //get the 2nd operand of ld, which is the source register
  147. ch = (op1[0]-48)| ((op2[0]-48) << 3); //form bits 11-0 of machine code. 48 is ASCII value of '0'
  148. program[counter]=0x2000+((ch)&0x00ff); //form the instruction and write it to memory
  149. counter++; //skip to the next empty location in memory
  150. }
  151. else if (strcmp(token,"st")==0) //-------------ST INSTRUCTION--------------------
  152. {
  153. //to be added
  154. }
  155. else if (strcmp(token,"jz")==0) //------------- CONDITIONAL JUMP ------------------
  156. {
  157. //to be added
  158. }
  159. else if (strcmp(token,"jmp")==0) //-------------- JUMP -----------------------------
  160. {
  161. op1 = strtok(NULL,"\n\t\r "); //read the label
  162. jumptable[noofjumps].location = counter; //write the jz instruction's location into the jumptable
  163. op2=(char*)malloc(sizeof(op1)); //allocate space for the label
  164. strcpy(op2,op1); //copy the label into the allocated space
  165. jumptable[noofjumps].label=op2; //point to the label from the jumptable
  166. noofjumps++; //skip to the next empty location in jumptable
  167. program[counter]=0x5000; //write the incomplete instruction (just opcode) to memory
  168. counter++; //skip to the next empty location in memory.
  169. }
  170. else if (strcmp(token,"add")==0) //----------------- ADD -------------------------------
  171. {
  172. op1 = strtok(NULL,"\n\t\r ");
  173. op2 = strtok(NULL,"\n\t\r ");
  174. op3 = strtok(NULL,"\n\t\r ");
  175. chch = (op1[0]-48)| ((op2[0]-48)<<3)|((op3[0]-48)<<6);
  176. program[counter]=0x7000+((chch)&0x00ff);
  177. counter++;
  178. }
  179. else if (strcmp(token,"sub")==0)
  180. {
  181. //to be added
  182. }
  183. else if (strcmp(token,"and")==0)
  184. {
  185. //to be added
  186. }
  187. else if (strcmp(token,"or")==0)
  188. {
  189. //to be added
  190. }
  191. else if (strcmp(token,"xor")==0)
  192. {
  193. //to be added
  194. }
  195. else if (strcmp(token,"not")==0)
  196. {
  197. op1 = strtok(NULL,"\n\t\r ");
  198. op2 = strtok(NULL,"\n\t\r ");
  199. ch = (op1[0]-48)| ((op2[0]-48)<<3);
  200. program[counter]=0x7500+((ch)&0x00ff);
  201. counter++;
  202. }
  203. else if (strcmp(token,"mov")==0)
  204. {
  205. //to be added
  206. }
  207. else if (strcmp(token,"inc")==0)
  208. {
  209. op1 = strtok(NULL,"\n\t\r ");
  210. ch = (op1[0]-48)| ((op1[0]-48)<<3);
  211. program[counter]=0x7700+((ch)&0x00ff);
  212. counter++;
  213. }
  214. else if (strcmp(token,"dec")==0)
  215. {
  216. //to be added
  217. }
  218. else //------WHAT IS ENCOUNTERED IS NOT AN INSTRUCTION BUT A LABEL. UPDATE THE LABEL TABLE--------
  219. {
  220. labeltable[nooflabels].location = counter; //buraya bir counter koy. error check
  221. op1=(char*)malloc(sizeof(token));
  222. strcpy(op1,token);
  223. labeltable[nooflabels].label=op1;
  224. nooflabels++;
  225. }
  226. token = strtok(NULL,",\n\t\r ");
  227. }
  228. }
  229.  
  230.  
  231. //================================= SECOND PASS ==============================
  232.  
  233. //supply the address fields of the jump and jz instructions from the
  234. int i,j;
  235. for (i=0; i<noofjumps;i++) //for all jump/jz instructions
  236. {
  237. j=0;
  238. while ( strcmp(jumptable[i].label , labeltable[j].label) != 0 ) //if the label for this jump/jz does not match with the
  239. j++; // jth label in the labeltable, check the next label..
  240. program[jumptable[i].location] +=(labeltable[j].location-jumptable[i].location-1)&0x0fff; //copy the jump address into memory.
  241. }
  242.  
  243.  
  244.  
  245.  
  246. // search for the start of the .data segment
  247. rewind(fp);
  248. while(fgets(line,sizeof line,fp)!= NULL) //skip till .data, if no .data, also ok.
  249. {
  250. token=strtok(line,"\n\t\r ");
  251. if (strcmp(token,".data")==0 )
  252. break;
  253.  
  254. }
  255.  
  256.  
  257. // process the .data segment and generate the variabletable[] array.
  258. int dataarea=0;
  259. while(fgets(line,sizeof line,fp)!= NULL)
  260. {
  261. token=strtok(line,"\n\t\r ");
  262. if (strcmp(token,".code")==0 ) //go till the .code segment
  263. break;
  264. else if (token[strlen(token)-1]==':')
  265. {
  266. token[strlen(token)-1]='\0'; //will not cause memory leak, as we do not do malloc
  267. variabletable[noofvariables].location=counter+dataarea;
  268. op1=(char*)malloc(sizeof(token));
  269. strcpy(op1,token);
  270. variabletable[noofvariables].name=op1;
  271. token = strtok(NULL,",\n\t\r ");
  272. if (token==NULL)
  273. program[counter+dataarea]=0;
  274. else if (strcmp(token, ".space")==0)
  275. {
  276. token=strtok(NULL,"\n\t\r ");
  277. dataarea+=atoi(token);
  278. }
  279. else if((token[0]=='0')&&(token[1]=='x'))
  280. program[counter+dataarea]=hex2int(token+2)&0xffff;
  281. else if (( (token[0])=='-') || ('0'<=(token[0])&&(token[0]<='9')) )
  282. program[counter+dataarea]=atoi(token)&0xffff;
  283. noofvariables++;
  284. dataarea++;
  285. }
  286. }
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293. // supply the address fields for the ldi instructions from the variable table
  294. for( i=0; i<noofldis;i++)
  295. {
  296. j=0;
  297. while ((j<noofvariables)&&( strcmp( lditable[i].name , variabletable[j].name)!=0 ))
  298. j++;
  299. if (j<noofvariables)
  300. program[lditable[i].location] = variabletable[j].location;
  301. }
  302.  
  303. // supply the address fields for the ldi instructions from the label table
  304. for( i=0; i<noofldis;i++)
  305. {
  306. j=0;
  307. while ((j<nooflabels)&&( strcmp( lditable[i].name , labeltable[j].label)!=0 ))
  308. j++;
  309. if (j<nooflabels){
  310. program[lditable[i].location] = (labeltable[j].location)&0x0fff;
  311. printf("%d %d %d\n", i, j, (labeltable[j].location));
  312. }
  313. }
  314.  
  315. //display the resulting tables
  316. printf("LABEL TABLE\n");
  317. for (i=0;i<nooflabels;i++)
  318. printf("%d %s\n", labeltable[i].location, labeltable[i].label);
  319. printf("\n");
  320. printf("JUMP TABLE\n");
  321. for (i=0;i<noofjumps;i++)
  322. printf("%d %s\n", jumptable[i].location, jumptable[i].label);
  323. printf("\n");
  324. printf("VARIABLE TABLE\n");
  325. for (i=0;i<noofvariables;i++)
  326. printf("%d %s\n", variabletable[i].location, variabletable[i].name);
  327. printf("\n");
  328. printf("LDI INSTRUCTIONS\n");
  329. for (i=0;i<noofldis;i++)
  330. printf("%d %s\n", lditable[i].location, lditable[i].name);
  331. printf("\n");
  332. fclose(fp);
  333. fp = fopen("RAM","w");
  334. fprintf(fp,"v2.0 raw\n");
  335. for (i=0;i<counter+dataarea;i++)
  336. fprintf(fp,"%04x\n",program[i]);
  337. }
  338. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement