사용자가 작성한 어셈블리 프로그램(원시 프로그램)을 목적 프로그램으로 번역하는 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 |