Social Icons

twitterfacebookgoogle plusrss feedemail

6/11/2010

作業系統上機考程式碼


系統程式上機練習題,這個程式主要是仿組譯器的製作,當然這個簡單太多了。程式是這個樣子的,如果我們再筆記本上輸入組合語言的程式碼,經由這個程式會自動幫我們轉成機器看得懂的目的碼。
因為我是在考試前一天趕出來的,所以程式碼並沒有寫得很好,可能可以寫得再精簡一點,不過最近考試很多沒什麼時間可以改。


abc.txt的內容如下:
copy start 1000

first stl retaddr
cloop sub data1
lda length
comp zero
beq cloop

data1 byte 55 66
length byte 7
byte 99
zero byte 0

retaddr byte 0 0 0



程式碼大致上如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cstdlib>
#include <iostream>

typedef struct _sym {
        int line, count,address;
        char item[10][20];
        struct _sym *next;
        } SymbolTable;
SymbolTable *phead,*ptr,*pNew;
/*產生新空間*/
struct _sym *creat(int line)
{
SymbolTable *New;// 宣告一個節點指標
New = (SymbolTable *)malloc(sizeof(SymbolTable)); // 指標指向一個新的結構記憶體
New->line = line;
New->next= NULL;
return (New); // 傳回New指標
}
/*反轉單項鏈結副程式*/
struct _sym *invert(SymbolTable *phead)
{
    SymbolTable *middle,*trail;
    middle=NULL;
    while(phead){
    trail=middle;
    middle=phead;
    phead=phead->next;
    middle->next=trail;
    }
return middle;
}
/*利用找相對應的字做文字檔案的搬移動作*/
typedef struct _opcode
{
        char opname[10];
        char *code;
} operation;
operation op[10] = {{"add","18"},{"sub","1c"},{"stl","14"},{"lda","00"},{"comp","28"},{"beq","10"}};

void begin_parsing(FILE *fp)
  int i;
  for (i=1; !feof(fp); i++)
  {
      char buffer[200];
      fgets(buffer,200,fp);
     
    
        if(i==1)
        {//用來存開始的指標
        phead = creat(i);
        ptr = phead;
        }
        else
        {
        pNew = creat(i); 
        ptr->next= pNew;
        ptr = pNew; 
        }

      int j=0;
      char *pch;
      pch = strtok (buffer," ,.\t\n");
       
      while (pch != NULL)
          {//將字串寫入
             strcpy(ptr->item[j],pch);
           
             pch = strtok(NULL, " ,.\t\n");
            j++;
          }
   
      ptr->count=j;   
    
  }

}

int main(int argc, char *argv[])
{
  FILE *fp,*fp1;
  fp=fopen("abc.txt", "r");
  fp1=fopen("cde.txt","w");
  fclose(fp1);
  begin_parsing(fp);
  fclose(fp);

 
  printf("Praising .....\n");
  printf("ln\t(addr)\t(ct):\tfield1\tfield2\tfield3\t\t\top\n");


  /********************************排版******************************/
  int addcount=0,cal;
  ptr=phead;
  char *pch1;   
  while(phead != NULL)// 直到phead== NULL時跳出
   {
    int m=0,i,n=0;
    for(i=phead->count;i>0;i--)
    {
       m++;
       n++;//判斷有沒有字
    }

    if (0==strcmp(phead->item[1],"start"))//比較字串是否為start
    {
       sscanf(phead->item[2],"%x",&addcount);
       phead->address=addcount;
       goto next;
    }

    phead->address=addcount;
    if (0==strcmp(phead->item[1],"byte"))//比較字串是否為byte
        m=m-2;
   
    addcount+=m;//加上位址
next:
    if(n==0)//假如遇到沒有字的,則指向下個指標
    {
    phead=phead->next;
    continue;
    }
    int num;
    char a[1]={0};
    for(num=0;num<6;num++)
    {//如果第一個字為指令時
        if(0==strcmp(phead->item[0],op[num].opname))
        {
            cal=phead->count;
            for(cal;cal>0;cal--)
                strcpy(phead->item[cal],phead->item[cal-1]);
            pch1=&a[0];
            strcpy(phead->item[0],pch1);
            phead->count++;
            n=phead->count;
            addcount++;
        }
               
    }
    if(0==strcmp(phead->item[0],"byte"))
        {//假如第一個字是BYTE
            cal=phead->count;
            for(cal;cal>0;cal--)
                strcpy(phead->item[cal],phead->item[cal-1]);
            pch1=&a[0];
            strcpy(phead->item[0],pch1);
            phead->count++;
            n=phead->count;
            addcount--;
        }
    phead->count=n;
    cal=phead->line;
    phead=phead->next;//指向下個指標
            
   }

  /*******************做文字替換**************************/
  phead = ptr;
  int i=0,sav;
  char *pch;
  while(phead != NULL)
  {

  pch=phead->item[2];
  sav=phead->line;//存放現在所在行數,以供等等回來用
  int addresschange=0;//用來存放等等如果找到一樣的字的address
  phead = ptr;
  for(i=0;i<cal;i++)//找相同的字
  {
     
      if(0==strcmp(pch,phead->item[0]))
      {
          addresschange=phead->address;
          break;
      }
      phead=phead->next;

  }
  if(addresschange==0)//0表示沒找到一樣的字
  {
      phead = ptr;
       for(i=1;i<sav+1;i++)
      {
      phead=phead->next;
      }
       if(phead->count==0&&phead->line<cal+1){//判斷下一行文字是不是空的字串
          phead=phead->next;//如果是空字串則在往下一個指標指向
          continue;
       }
       else if(phead->line>cal)//如果已經找到最後一行了,則可以跳出準備開始印出
        break;
  }
  else{//表示addresschange有值,也就是有找到相同的文字
  phead=ptr;
    for(i=1;i<sav;i++)//回到原來位置
    {
     phead=phead->next;
    }
    sprintf(pch,"%x",addresschange);//將值先放到pch
    strcpy(phead->item[2],pch);//再把值丟給item

  }
  addresschange=0;//addresschange清空,以便下次繼續找尋
  phead=phead->next;//指向下個指標

  }

    /*********************印出********************/
    int m,n,num;
    phead = ptr;
    for(i=0;i<cal;i++)  {
    printf("%2d\t",phead->line);
    printf("(%x)\t",phead->address);
    printf("(%d)\t",phead->count);

    m=0;
    for(i=phead->count;i>0;i--)//將字串印出
    {
        printf("%s\t",phead->item[m]);
        m++;
    }
    //另外如果要印出運算碼則用以下程式
    for(num=0;num<6;num++)
    {
        if(0==strcmp(phead->item[1],op[num].opname))
        {
       if(m==4)
           printf("\t%s%s",op[num].code,phead->item[2]);
       else if(m==5)
           printf("%s%s",op[num].code,phead->item[2]);
       else if(m==3)
           printf("\t\t%s%s",op[num].code,phead->item[2]);
        }
               
    }
    if(0==strcmp(phead->item[1],"byte"))
        {
       if(m==4)
       printf("\t%s%s",phead->item[2],phead->item[3]);
       else if(m==5)
       printf("%s%s%s",phead->item[2],phead->item[3],phead->item[4]);
       else if(m==3)
       printf("\t\t%s%s",op[num].opname,phead->item[2]);
        }
     //

    printf("\n");
    phead=phead->next;
       
    if(phead->count==0&&phead->line<cal)//避免印到空的字串
       phead=phead->next;
    if(phead->line>cal)
         break;
    }

  printf("\n");
   system("PAUSE");
  return 0;
}

沒有留言:

張貼留言

俗話說
凡走過必留下痕跡,凡住過必留下鄰居
凡爬過必留下樓梯,凡來過必留下IP
看過文章之後歡迎留下您寶貴的意見喔!

 
 
无觅相关文章插件,迅速提升网站流量