본문 바로가기
C.E/C, C++

C로 정말 간단한 어셈블러 구현하기.

by 책읽는구리 2009. 1. 15.
반응형

기능 :
 Free Format의 SIC SOurce FIle을 읽어서 FIxed FOrmat의 SIC Source FIle로 변환
 변환한 FIle에 행 번호를 추가해 리스트 파일 생성 후 화면에 출력
 심볼에 대한 참조 리스트를 화면에 출력

[헤더파일]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define buf_len 62 //buf 길이

//symbol table 자료구조 내용
typedef struct symtab{
 char symbol[10]; //symbol값 저장
 char defined[10]; //정의된 line저장
 struct used *used_head; //이 symbol이 사용된 라인값들의 처음을 가르키는 리스트 포인터
 struct used *used_rear;
 symtab *next; //다음 symbol 리스트 가르키는 포인터
} symtab;

//used의 내용을 저장하는 리스트
typedef struct used{
 char used_line[5];
 used *next;
} used;

struct symtab *head, *rear;  //symtabl의 처음과 끝을 가르키는 포인터

/*
이름 : 심볼 테이블 검사 및 Used 함수
목적 : 심볼 테이블에서 심볼을 검사해 존재하면 Used값 추가
*/
void check_symbol(char sym[10], char line[3]);

/*
이름 : 심볼 테이블 추가 함수
목적 : 심볼 테이블에 Symbol과 Defined 값을 추가한다.
*/
void add_label(char *ch[4]);

/*
이름 : Fixed Format Source 파일 생성 함수
목적 : Free format Source 파일을 읽어와 Fixed Format Source 파일로 변환
*/
void Change_Free_ToFixed(void);

/*
이름 : Source List 파일 생성 함수
목적 : Fixed Format Source 파일을 읽어 행을 추가하고 파일로 출력
*/
void Change_Fixed_ToList(void);

/*
이름 : 심볼 테이블 작성 함수
목적 : 심볼 테이블을 생성 및 작성
*/
void creat_symtab_1pass(void);
void creat_symtab_2pass(void);

/*
이름 : 파일 출력 함수
인자 : file_name[20] : 출력할 파일 이름
목적 : 파일 내용 출력
*/
void Print_File(char file_name[20]);

/*
이름 : Cross-reference List 출력 함수
목적 : 심볼 테이블을 이용해 reference list를 출력
*/
void Cross_List_print(void);

[C파일]

#include "ConversionProgram.h"

int main(void){
 Change_Free_ToFixed(); //Fixed Format Source 파일 생성
 printf("#Fixed Foramt Source 파일이 생성되었습니다...\n");
 Change_Fixed_ToList(); //Source List 파일 생성
 printf("#Source List 파일이 생성되었습니다...\n\n");
 Print_File("ListSourcefile.txt");//파일 출력
 creat_symtab_1pass(); //1pass
 creat_symtab_2pass(); //2pass
 Cross_List_print(); //최종 출력
 return 0;
}

//Fixed Format Source 파일 생성 함수
void Change_Free_ToFixed(void){
 FILE *readfile;
 FILE *writefile;
 int i=0;
 char buf[buf_len], *p, *s[3], *k = ".\n";
 
 readfile = fopen("SicSourceFile.txt","r+");
 writefile = fopen("FixedSourceFile.txt","w+");
 while( fgets(buf,buf_len,readfile) ){
  p=strtok(buf," ");
  if(p) s[i++] = p;
  while(p!=NULL){
   p=strtok(NULL, " ");
   if(p) s[i++] = p;
  }
  if( strcmp(s[0], k)==0){
   
  }
  else{
   switch(i){
   case 1:
    fprintf(writefile,"%s\t", " ");
    fprintf(writefile,"%s", s[0]);
    break;
   case 2:
    fprintf(writefile,"%s\t", " ");
    fprintf(writefile,"%s\t", s[0]);
    fprintf(writefile,"%s", s[1]);
    break;
   case 3:
    fprintf(writefile,"%s\t", s[0]);
    fprintf(writefile,"%s\t", s[1]);
    fprintf(writefile,"%s", s[2]);
    break;
   }
  }
  i=0;
 }
 fclose(readfile);
 fclose(writefile);
}

//Source List 파일 생성 함수
void Change_Fixed_ToList(void){
 FILE *readfile;
 FILE *writefile;
 char buf[buf_len];
 int i=1;
 readfile = fopen("FixedSourceFile.txt","r+");
 writefile = fopen("ListSourcefile.txt","w+");

 while( fgets(buf,buf_len,readfile) ){
  fprintf(writefile, "%d\t",i++);
  fprintf(writefile, "%s", buf);
 }
 fclose(readfile);
 fclose(writefile);

}

//파일 출력 함수
void Print_File(char file_name[20]){
 FILE *readfile;
 char buf[buf_len];

 readfile = fopen(file_name,"r+");
 printf("==Source List file 출력=============\n");
 while( fgets(buf,buf_len,readfile) ){
  printf("%s", buf);
 }
 printf("\n");
 fclose(readfile);
}

//symbol table 1pass(sybtab작성 부분)
void creat_symtab_1pass(){
 FILE *readfile;
 char buf[buf_len], *s[4], *p;
 int i=0;

 readfile = fopen("ListSourcefile.txt","r+");
 while(fgets(buf,buf_len,readfile)){//라인에서 한줄을 읽어와
  p=strtok(buf," \t");
  if(p) s[i++] = p;
  while(p!=NULL){
   p=strtok(NULL, " \t");
   if(p) s[i++] = p;
  }
  if(i==4) add_label(s); //symbol을 symtab에 추가
  i=0;
 }
}

//symtab 추가 함수
void add_label(char *ch[4]){
 symtab *new_tab;
 new_tab = (symtab *)malloc(sizeof(symtab));
 if(head==NULL){
  head = new_tab;
  rear = new_tab;
 }
 else{
  rear->next = new_tab;  //맨 끝의 리스트에 새로운 symtab추가 (next)추가
  rear = new_tab; //rear포인터가 맨 끝의 리스트를 가르키도록 수정
 } 
 new_tab->next = NULL;
 new_tab->used_head = NULL;
 new_tab->used_rear = NULL;
 strcpy(new_tab->defined,ch[0]);
 strcpy(new_tab->symbol,ch[1]);
}

//symbol table 2pass(used 작성 부분)
void creat_symtab_2pass(){
 FILE *readfile;
 char buf[buf_len], *s, *p, *t, *line;
 int i=0, temp=0;
  //마지막 토큰만 분리하는 부분
 readfile = fopen("ListSourcefile.txt","r+");
 while(fgets(buf,buf_len,readfile)){
  p=strtok(buf,"\t\n");
  if(p){
   line = p;
   i++;
  }
  while(p!=NULL){
   p=strtok(NULL, "\t\n");
   if(p){
    s = p;
    i++;
   }
  }
    // 오퍼랜드를 구분자 , 를 이용해서 분리한다.
  if( i==4 ){
   p = strtok(s, ",");
   if(p) s = p;
   while(p!=NULL){
    p = strtok(NULL, " \n");
    if(p){
     t = p;
     i=1;
    }
   }
      // ,구분자 뒤에 값을 심볼 테이블에서 검사
   if(i==1){
    check_symbol(t, line);
   }
      // ,구분자 전 값을 심볼 테이블에서 검사
   check_symbol(s, line);
  }
  i=0;
 }
}

// symbol 검사 함수
void check_symbol(char sym[10], char line[3]){
 symtab *p=head;
 used *temp;
 temp = (used *)malloc(sizeof(used));
 while(p!=NULL){
  if(strcmp(sym,p->symbol)==0){
   if(p->used_head==NULL){
    p->used_head = temp;
    p->used_rear = temp;
   }
   else{
    p->used_rear->next = temp;
    p->used_rear = temp;
   }
   temp->next = NULL;
   strcpy(temp->used_line,line);
  }
  p = p->next;
 }
}

//Cross-reference List 출력 함수
void Cross_List_print(){
 symtab *p = head;
 printf("==Cross List file 출력=============\n");
 printf("symbol\tDefined\tUsed\n");
 while(p!=NULL){
  printf("%-8s", p->defined);
  printf("%-8s", p->symbol);
  used *q = p->used_head;
  while(q!=NULL){
   printf("%-3s", q->used_line);
   q=q->next;
  }
  p=p->next;
  printf("\n");
 }
}

 

 

 

 

반응형

댓글