본문 바로가기

ASSEMBLY

MAKING ASSEMBLYSYSTEM SOFTWARE

사용자가 작성한 어셈블리 프로그램(원시 프로그램)을 목적 프로그램으로 번역하는 SIC 어셈블러를 구현하기

 

<pass1 실행결과>

 

<pass2 실행결과>

-xshell

-Dev-c

->출력결과를 두개로 출력한 이유

C’EOF’ operand인 목적코드를 생성할 때 Dev-c에서는 맞게 돌아가나 xshell에서는 이상하게 돌아가서.

->길이 출력 실패

새 문장이 시작될때마다 그 문장의 길이를 출력해 주어야한다. 나의 알고리즘은 순서대로 넣어진 opcode를 추적하여 발견될 때마다 즉시 출력해줌으로써 미리 길이를 구할 수가 없다.

<해결책>

출력해야하는 목적코드를 미리 배열에 저장하여 맨 마지막에 출력해주면 길이와 함께 출력가능.

 

[sample.s]

5 COPY START 1000

10 FIRST STL RETADR

15 CLOOP JSUB RDREC

20 LDA LENGTH

25 COMP ZERO

30 JEQ ENDFIL

35 JSUB WRREC

40 J CLOOP

45 ENDFIL LDA EOF

50 STA BUFFER

55 LDA THREE

60 STA LENGTH

65 JSUB WRREC

70 LDA RETADR

75 RSUB

80 EOF BYTE C’EOF’

85 THREE WORD 3

90 ZERO WORD 0

95 RETADR RESW 1

100 LENGTH RESW 1

105 BUFFER RESB 4096

125 RDREC LDX ZERO

130 LDA ZERO

135 RLOOP TD INPUT

140 JEQ RLOOP

145 RD INPUT

150 COMP ZERO

155 JEQ EXIT

160 STCH BUFFER,X

165 TIX MAXLEN

170 JLT RLOOP

175 EXIT STX LENGTH

180 RSUB

185 INPUT BYTE X’F1’

190 MAXLEN WORD 4096

210 WRREC LDX ZERO

215 WLOOP TD OUTPUT

220 JEQ WLOOP

225 LDCH BUFFER,X

230 WD OUTPUT

235 TIX LENGTH

240 JLT WLOOP

45 RSUB

250 OUTPUT BYTE X’05’

255 END FIRST

 

<소스코드>

[assembly.c]

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

/* SYMTAB를 위한 구조체 */

struct SYMTAB {

           char symcode[10];

           int loc1;

}Wordtab[100];

/* OPTAB부분을 저장시키기  위한 구조체 */

struct OPTAB {

           char opcode[10];

           int loc2;

}Wordtab2[100];

/*OPERAND를 위한 구조체*/

struct OPERTAB{

           char operand[10];

}Wordtab3[100];

/*op코드가 저장되어있는 optable*/

struct OPERCODE{

           char name[20];

           int len;

}Wordtab4[] = {{"STL",20},{"JSUB",72},{"LDA",00},{"COMP",40},{"JEQ",48},{"J",60},{"STA",12},{"RSUB",76},{"LDX",04},{"TD",224},

{"RD",216},{"STCH",216},{"TIX",44},{"JLT",56},{"WD",220},{"STX",16},{"LDCH",80}};

void pass1(char *bp,int *opnum,int *LOC, int *opernum, int *symnum,int *startAd);

void pass2(int startad, int LOC,int opernum, int symrnum,int opnum);

int main() {

           FILE *fp;

           char buf[80];

           int LOC;

           int symnum=0; //sym의 갯수

           int opnum=0; // opcode의 갯수

           int opernum=0; //operan의 갯수

           int startAd=0;

 

           if ((fp = fopen("sample.s", "r")) == NULL) {

                     fprintf(stderr, "file not found...\n"); exit(1);

           }

           /*pass1 만들기*/

           int opnum2=0;

           while(fgets(buf, sizeof(buf), fp) != NULL) {

                               pass1(buf, &opnum, &LOC, &opernum, &symnum, &startAd);

           }

          

           fclose(fp);

}

/*  pass1

1. 한줄씩 읽어들인다.

      2. Label이 있는 줄인지 구분하여 공백을 두고 자른다.

         3. 각각 구조체에 넣어준다.

            4. LOC를 설정하여준다*/

void pass1(char *bp,int *opnum,int *LOC, int *opernum, int *symnum,int *startAd)

{

           int i=0;

           char *cp;

           int n = 0;

           char *what;

           char *a[5];

           int num;

           int len;

           int len2;

           char type[3];

           int x;

 

 

           for(cp = strtok(bp, "\n"); cp != NULL; ) {

                                i = 0;

                     for(what = strtok(cp, " "); what != NULL; ) {

                                          a[i] = what;

                                          i++;

                                          what = strtok(NULL," ");

                                }       //우선 한 라인의 단어를 배열에 저장                              

                                if(i==4){        //만약 label이 존재한다면

                                          strcpy(Wordtab2[*opnum].opcode,a[2]); // optable opcode 저장

                                          Wordtab2[*opnum].loc2 = *LOC;

                                          strcpy(Wordtab3[*opernum].operand, a[3]); //OPERTAB  operand 저장

                                          if(strcmp(Wordtab2[*opnum].opcode,"START")==0){  //시작주소 설정

                                          int len = strlen(Wordtab3[0].operand);

                                                     int res; //시작주소 16진수 10진수로 바꾸기

                                                    res = (int)strtol(Wordtab3[0].operand, NULL, 16);

                                                    *startAd = res;

                                                     *LOC = *startAd;

                                                     strcpy(Wordtab[0].symcode,a[1]);

                                          }

                                          for(num = 0; num<*symnum; num++){ // -->Lable 저장

                                                     if( Wordtab[num].symcode != a[1]){

                                                                strcpy(Wordtab[*symnum].symcode,a[1]);

                                                                Wordtab[*symnum].loc1 = *LOC;

                                                               }         

                                                     }

                                                     printf("%.4X  ",Wordtab[*symnum].loc1);

                                                     printf("%s    %s   %s\n",Wordtab[*symnum].symcode,Wordtab2[*opnum].opcode,Wordtab3[*opernum].operand);

                                                     if(strcmp(Wordtab2[*opnum].opcode,"WORD")==0)

                                                                *LOC= *LOC + 3;

                                                     else if(strcmp(Wordtab2[*opnum].opcode,"RESW")==0)

                                                                *LOC=*LOC+atoi(Wordtab3[*opernum].operand);

                                                     else if(strcmp(Wordtab2[*opnum].opcode,"BYTE")==0){

                                                                 type[0] = Wordtab2[*opernum].opcode[0];

                                                                if(strcmp(type,"X")==0)

                                                                          *LOC=*LOC+1;

                                                                else{

                                                                                     len2=strlen(Wordtab2[*opnum].opcode) -2;

                                                                                     *LOC = *LOC + len2;      

                                                                          }

                                              }

                                                     else

                                                     if(strcmp(Wordtab2[*opnum].opcode,"START")!=0){  

                                                     *LOC = *LOC + 3;

                                                     }                              

                                                     *opnum = *opnum +1;

                                                     *opernum = *opernum + 1;

                                                     *symnum= *symnum + 1;

                                          }

                                         

                                else{                                               

                                          strcpy(Wordtab2[*opnum].opcode, a[1]);   // optable opcode 저장

                                          Wordtab2[*opnum].loc2 = *LOC;

                                          if(strcmp(Wordtab2[*opnum].opcode,"RSUB")!=0){

                                          strcpy(Wordtab3[*opernum].operand, a[2]); //OPERTAB  operand 저장

                                          }

                                          printf("%.4X  ",*LOC);

                                          printf("          %s   %s\n",Wordtab2[*opnum].opcode,Wordtab3[*opernum].operand);

                                          /*end가 나왔을 때 pass2로 이동 && 총 길이는 패스2에서 구함*/

                                          if(strcmp(Wordtab2[*opnum].opcode,"END")==0){

                                                     pass2(*startAd,*LOC,*opernum,*symnum,*opnum);

                                          }

                                          *opnum = *opnum +1;

                                          *opernum = *opernum + 1;

                                          *LOC= *LOC + 3;

                                }

                               

                                cp = strtok(NULL, "\n");

           }

}

/*pass2*/

void pass2(int startad, int LOC,int opernum, int symnum,int opnum){

           int len;

           int i;

           int j;

           int xx;

           int count=0;

           int staddr[10];

 

           if(strcmp(Wordtab2[0].opcode,"START")==0){

                     len = LOC - startad;

                     printf("H^%s %.4X^%.4X\nT^00%X^",Wordtab[0].symcode,startad,len,startad);

           }

           for(i=1; i<=opernum; i++){

                     count++;

                     if((count%10)==0){  //optable 10개 검사후 줄 끊기

                                printf("\n");

                                printf("T^");

                                printf("%.6X^",Wordtab2[i+1].loc2);

                     }

                     if(strcmp(Wordtab2[i].opcode,"END")==0){  //end코드가 나오면 마무리

                                printf("\n");

                                printf("E^00%X\n",startad);

                                exit(1);

                     }

                      else if((strcmp(Wordtab2[i].opcode,"BYTE")==0)||strcmp(Wordtab2[i].opcode,"WORD")==0){

                                if(strcmp(Wordtab2[i].opcode,"WORD")==0)

                                          printf("0000%s^",Wordtab3[i].operand);

                                else if(strcmp(Wordtab2[i].opcode,"BYTE")==0){

                                                     if(Wordtab3[i].operand[0]=='X'){   

                                                                for(xx=3; xx<strlen(Wordtab3[i].operand)-2;xx++){

                                                                                     printf("%c",Wordtab3[i].operand[xx]);

                                                                }

                                                                printf("^");

                                                     }

                                                     else if(Wordtab3[i].operand[0]=='C'){

                                                                for(xx=3; xx<strlen(Wordtab3[i].operand)-2;xx++){

                                                                                     printf("%.2X",Wordtab3[i].operand[xx]);

                                                                }

                                                                printf("^");

                                                     }

                                }

                     }

                     else if(strcmp(Wordtab2[i].opcode,"RSUB")==0){

                                for(xx=0; xx<sizeof(struct OPERCODE);xx++){

                                                     if(strcmp(Wordtab2[i].opcode,Wordtab4[xx].name)==0){

                                                                printf("%X0000^",Wordtab4[xx].len);

                                                     }

                                          }

                                }

                     else{

                     for( j=1; j<symnum; j++){

                                if(strcmp(Wordtab3[i].operand,Wordtab[j].symcode)==0){

                                          for(xx=0; xx<sizeof(struct OPERCODE);xx++){

                                                     if(strcmp(Wordtab2[i].opcode,Wordtab4[xx].name)==0){

                                                                printf("%X",Wordtab4[xx].len);

                                                     }

                                          }

                                printf("%X^",Wordtab[j].loc1);

                                }

                     }

                     }

           }

}

 

'ASSEMBLY' 카테고리의 다른 글

System Software _ project 5  (0) 2019.06.26
System Software _ project 4  (0) 2019.06.26
System Software _ project 2  (0) 2019.06.26
System Software _ project 1  (0) 2019.06.26