主题: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字一行。
题目大意:
考虑一个微处理器,具有以下特征:
·每个字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字一行。