题目大意:
现要求你模拟一台简单的计算机,只有8中机器指令,以及一个只有32字节的内存(MM)和一个8字节的累加器(AC),程序计数器(PC)的长度为5字节,用于保存下一条指令的地址,内存既可以存数据也可以存指令。
每条指令只有1字节,其中:
000XXXXX STA X:将AC中的值压入X地址内存单元内
001XXXXX LDA X:将内存单元X处的数据压入AC内
010XXXXX BEQ X:如果AC为0则将X覆盖至PC
011----- NOP :空操作
100----- DEC :AC--
101----- INC :AC++
110XXXXX JMP X:将X覆盖至PC
111----- HLT :程序终止
现有多个测例(测例数不确定),每个测例中初始时,AC和PC为0,此时PC指向MM的0号字节,然后先将32条指令读入MM中,接着就顺序执行指令直至程序结束(假设所有程序都是会终止的),对于每个测例输出程序执行完毕后AC的内容,所有的输入输出都是二进制的,并且左边为高位右边为低位。
注释代码:
/*
* Problem ID : POJ 2410 Simple Computers
* Author : Lirx.t.Una
* Language : C
* Run Time : 0 ms
* Run Memory : 156 KB
*/
#include <memory.h>
#include <stdio.h>
//byte length
//一个字节的长度
#define BYTEL 8
//number of byte
//表示主存有多少个字节
#define BYTEN 32
//instruction,获取指令部分
#define INST ( MM[PC] >> 5 )
//address,获取地址部分
#define ADDR ( MM[PC] & 0x1F )
//PC++,即PC前移一位
#define PCPP ( PC = ++PC & 0x1F )
typedef unsigned char byte;//一定要用unsigned
//否则右移的时候会补1!!!
enum INSTRUCTION {//枚举指令
STA,
LDA,
BEQ,
NOP,
DEC,
INC,
JMP,
HLT
};
byte MM[BYTEN];
byte AC;
byte PC;
char bs[BYTEN][BYTEL + 1];//bit string,位流,用于结束输入的字符串
void
EXCU(void) {//执行指令
int x;
while (1) {
switch (INST) {
case STA :
MM[ADDR] = AC;
PCPP;
break;
case LDA :
AC = MM[ADDR];
PCPP;
break;
case BEQ :
AC ? PCPP : ( PC = ADDR );
break;
case NOP :
PCPP;
break;
case DEC :
AC--;
PCPP;
break;
case INC :
AC++;
PCPP;
break;
case JMP :
PC = ADDR;
break;
case HLT :
for ( x = BYTEL - 1; x >= 0; x-- )//程序结束后输出AC
printf("%d", ( AC >> x ) & 1);//从高位到低位输出
putchar('\n');
return;
default : return;
}
}
}
int
main() {
int i, j;
while ( ~scanf("%s", *bs ) ) {
for ( i = 1; i < BYTEN; i++ )
scanf("%s", bs[i]);
memset(MM, 0, sizeof(MM));
for ( i = 0; i < BYTEN; i++ )//将位流解析成实际的数据
for ( j = 0; j < BYTEL; j++ )
MM[i] = ( MM[i] << 1 ) | ( bs[i][j] - '0' );
PC = 0;//初始化
AC = 0;
EXCU();
}
return 0;
}
无注释代码:
#include <memory.h>
#include <stdio.h>
#define BYTEL 8
#define BYTEN 32
#define INST ( MM[PC] >> 5 )
#define ADDR ( MM[PC] & 0x1F )
#define PCPP ( PC = ++PC & 0x1F )
typedef unsigned char byte;
enum INSTRUCTION {
STA,
LDA,
BEQ,
NOP,
DEC,
INC,
JMP,
HLT
};
byte MM[BYTEN];
byte AC;
byte PC;
char bs[BYTEN][BYTEL + 1];
void
EXCU(void) {
int x;
while (1) {
switch (INST) {
case STA :
MM[ADDR] = AC;
PCPP;
break;
case LDA :
AC = MM[ADDR];
PCPP;
break;
case BEQ :
AC ? PCPP : ( PC = ADDR );
break;
case NOP :
PCPP;
break;
case DEC :
AC--;
PCPP;
break;
case INC :
AC++;
PCPP;
break;
case JMP :
PC = ADDR;
break;
case HLT :
for ( x = BYTEL - 1; x >= 0; x-- )
printf("%d", ( AC >> x ) & 1);
putchar('\n');
return;
default : return;
}
}
}
int
main() {
int i, j;
while ( ~scanf("%s", *bs ) ) {
for ( i = 1; i < BYTEN; i++ )
scanf("%s", bs[i]);
memset(MM, 0, sizeof(MM));
for ( i = 0; i < BYTEN; i++ )
for ( j = 0; j < BYTEL; j++ )
MM[i] = ( MM[i] << 1 ) | ( bs[i][j] - '0' );
PC = 0;
AC = 0;
EXCU();
}
return 0;
}
单词解释:
processor:n, 处理器
accumulator:n, 累加器,蓄电池
Von Neumann Architecture:n, 冯·诺依曼体系
optional:adj. 可选的
operand:n, 操作数,运算对象
semantics:n, 语义,语义学
subtract:vt, 减去,扣掉
fetch:vt, 拿,取
prior:adj/adv, 优先的,在先的