回 帖 发 新 帖 刷新版面

主题:acm:微处理器模拟

原题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1072
题目大意:
考虑一个微处理器,具有以下特征:
·每个字4位
·地址是两个字,高位在前(高高低低)
·内存有256个字
·有两个累加器 A和B, 每个储存一个字
·有九条指令代码,每条指令至少占用一个字的空间
·每个4位代表的数字正好可以用16进制表示(0~9,A是10,B是11以此类推)
·下面是九条指令
指令    长度    描述
0    3    LD:参数为内存地址,将该地址的内容存入累加器A
1    3    ST:将累加器A的内容写入参数所指定的内存地址
2    1    SWP:交换累加器AB的内容
3    1    ADD:累加器AB相加;结果的地位存到A,高位存到B
4    1    INC:累加器A+1。允许上溢:F+1=0
5    1    DEC:累加器A-1。允许下溢:0-1=F
6    3    BZ:如果累加器A是0,下一条要执行的指令在参数所指定的位置。否则什么也不做
7    3    BR:下一条要执行的指令在参数指定的内存地址
8    1    STP:终止
·处理器总是从00地址开始运行

样例分析
下标    0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F 10 11
值    0  1  0  2  0  1  1  3  1  1  3  2  1  1  2  8  F  F

010:将地址为10的内容送至累加器A
2:交换累加器AB,结果累加器B的值为F
011:将地址为11的内容F送到累加器A
3:相加,结果1E。 低位放置A,高位放置B(A:E,B:1)
113:将累加器A的内容写入内存地址13
2:交换累加器AB
112:将累加器A的内容写入内存12
8:终止
运行完下面的代码后,内存应该如下:
0102011311321138FF1E000000000000000...
[code=c]
#include <stdio.h>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
    char mem[256];// map the memory
    char hex[17]="0123456789ABCDEF";//hex char
    unsigned char a,b,t;//argument a,b and temp
    
    char cr;// Enter 
    int i;//some compiler doesn't support(int i=0;;)
    
    FILE *IN;//input file
    FILE *OUT;//output ifle
    if((IN=fopen("input.txt","r"))==NULL)//successfully open?
    {
      printf("\nCannot open file, strike any key exit!\n");
      system("pause");
      exit(1);
    }
    
    while(1)//always loop
    {
            // read the code
            for(i=0;i<256;i++) if (fscanf(IN,"%c",&mem[i])==EOF) return 0;
            fclose(IN);//discard input file
            fscanf(IN,"%c",&cr);//read enter,if transform to acm this is a must
                                //if only using file, don't care 
            for(i=0;i<256;i++)
            {
                              //transform the code from str into hex
                              mem[i]-=48;//the numbers
                              if (mem[i]>9) mem[i]-=7;//capital letters
            }
            //description, ascii code
            //the ascii of number 0 is 48 so 
            //0:48  1:49  ... 9:57 (number:ascii code)
            //A:65 B:66 ... F:70    (letter:scii code)
            //so after the transformation:
            //0:0 1:1 ....9:9 A:10 B:11...
            
            if (mem[0]==8) break;//no any codes exist
            int ip=0;//start from mem[0]
            int flag=1;//indicates that the code is end
            while(flag)
            {
                    switch (mem[ip++])//ip starts with 0, after using, increasing
                    {
                           //LD: accumulator A is loaded from the memory address
                           case 0:
                           a=mem[(mem[ip]<<4)+mem[ip+1]];
                           ip+=2;//LD takes 3 words in memory
                           break;
                           
                           //ST: write value to the memory address from acc A
                           case 1:
                           mem[(mem[ip]<<4)+mem[ip+1]]=(a&=15);//15 binary:1111
                           ip+=2;//takes 3 words in memory
                           break;
                           
                           //SWP: acc A<==>acc B
                           case 2:
                           t=a;a=b;b=t;
                           break;//only takes 1 word in memory, so no need inc
                           
                           //ADD: acc A+ acc B, the result store as: low in A, high in B
                           case 3:
                           a+=b;
                           b=a>>4;
                           break;//only takes 1 word
                           
                           //INC: acc A+1, ps:F+1=0
                           case 4:
                           a++;
                           break; //only takes 1 word
                           
                           //DEC: acc A-1, ps:0-1=F
                           case 5:
                           a--;
                           break;
                           
                           //BZ: if acc A stored 0, than ip went to the momery address; if not, do nothing
                           case 6:
                           if ((a&=15)!=0)
                           {
                                          ip+=2;//takes 3 words
                                          break;
                           }
                           
                           //BR: ip goes to the memory address
                           case 7:
                           ip=((mem[ip]<<4)+mem[ip+1]);
                           break;//only takes 1 word
                           
                           //STP: halt
                           case 8:
                           flag=0;
                    }//end of switch
            }//end of while(f)
            
            if((OUT=fopen("output.txt","w"))==NULL){printf("Write error!");exit(1);}
            for(i=0;i<256;i++) 
            {
                               if (i%64==0) fprintf(OUT,"\n");
                               fprintf(OUT,"%c",hex[mem[i]]);                         
            }
            fprintf (OUT,"\n");
            fclose(OUT);
    }//end of while(1)
    
    return 0;
}
//end of main()
[/code]
测试方法,编译后创建一个input.txt文件,复制下面内容:
0102011311321128FF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
运行程序会出现一个output.txt文件,里面是处理后的内存,64字一行。

回复列表 (共1个回复)

沙发

呀。。。好像对注释的显示效果不太好啊。。。。请问应该怎么办?

我来回复

您尚未登录,请登录后再回复。点此登录或注册