#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned char ram[0x1000];
//采用小端序
//内存32kb,char型1个byte,8个bit
//0-16383 为代码段
//16384-32767 为数据段
//memset(ram, 0, sizeof(ram));
short ip = 0; //ip16位可以c寻址32k内存空间
unsigned int ir = 0; //指令寄存器
int flag = 0;
//8个16位寄存器组
short ax[8] = {0};
/*short ax2 = 0;
short ax3 = 0;
short ax4 = 0;
short ax5 = 0;
short ax6 = 0;
short ax7 = 0;
short ax8 = 0;*/
void reset() {
ip = 0;
ir = 0;
flag = 0;
memset(ax, 0, 8);
memset(ram, 0, 0x1000);
}
//显示内存状态
void show_cpu_state() {
printf("ip = %d\n", ip);
printf("flag = %d\n", flag);
printf("ir = %08x\n", ir);
printf("ax1 = %d ax2 = %d ax3 = %d ax4 = %d\n", ax[0], ax[1], ax[2], ax[3]);
printf("ax5 = %d ax6 = %d ax7 = %d ax8 = %d\n", ax[4], ax[5], ax[6], ax[7]);
}
//显示内存数据段与代码段状态
void show_ram_state() {
int i = 0;
printf("CodeSegment:");
for(;i < 64; i++) {
if(i % 4 == 0)
printf("\n");
printf("%02x ", ram[i]);
}
printf("\nDataSegment:");
for(i = 16384; i < 16896; i+=2) {
int n = 0;
n += ram[i+1];
n = n << 8;
n += ram[i];
if(i % 32 == 0)
printf("\n");
printf("%d ", n);
}
printf("\n");
}
//char指令转正2进制形式存储
void str2binary(int index, char instruction[]) {
int i = index;
int j = 0;
for(; j < 4; ++j) {
int k = j*8;
char temp[9];
strncpy(temp, instruction + k, 8);
//printf("%s Hex:", temp);
unsigned char n = 0;
unsigned char t = 0;
int p = 0;
int q = 0x80;
for(; p < 8; ++p) {
temp[p] -= 0x30;
t = temp[p] * q;
q = q >> 1;
n += t;
}
/*temp[0] -= 0x30;
t = temp[0] * 0x80;
n += t;
temp[1] -= 0x30;
t = temp[1] * 0x40;
n += t;
temp[2] -= 0x30;
t = temp[2] * 0x20;
n += t;
temp[3] -= 0x30;
t = temp[3] * 0x10;
n += t;
temp[4] -= 0x30;
t = temp[4] * 0x08;
n += t;
temp[5] -= 0x30;
t = temp[5] * 0x04;
n += t;
temp[6] -= 0x30;
t = temp[6] * 0x02;
n += t;
temp[7] -= 0x30;
t = temp[7] * 0x01;
n += t;*/
ram[i] = n;
//printf("%02x\n", ram[i]);
++i;
}
}
//函数功能:将文件中的指令读入内存的代码段
//输入:文件地址
//输出:无
void instructions_loading(char* fileAddr) {
FILE *fp;
fp=fopen(fileAddr,"r");
char instruction[33],ch[5];
int i=0;
while(fgets(instruction,33,fp) != NULL){
//printf("%s\n", instruction);
str2binary(4*i, instruction);
fgets(ch, 5, fp);
//printf("%c", ch);
i++;
}
//printf("%d", i);
//countl=i;
fclose(fp);
return;
}
//函数功能:将代码段中ip指向的指令取出,装入指令寄存器ir
//输入:全局的ip和ram
//输出:无
void load_instruction() {
ir = 0;
ir += ram[ip];
ir = ir << 8;
ir += ram[ip+1];
ir = ir << 8;
ir += ram[ip+2];
ir = ir << 8;
ir += ram[ip+3];
//show_cpu_state();
}
//函数功能:ip指向内存中下一条将要执行的地址
//输入:全局 ip
//输出:无
void inc_ip() {
ip += 4;
}
//函数功能:分析指令
//输入:ir中的指令
//输出:控制信号
int decode() {
unsigned int opcode = ir;
opcode = opcode >> 24;
switch(opcode) {
case 0: return 0;
case 1: return 1;
case 2: return 2;
case 3: return 3;
case 4: return 4;
case 5: return 5;
case 6: return 6;
case 7: return 7;
case 8: return 8;
case 9: return 9;
case 10: return 10;
case 11: return 11;
case 12: return 12;
}
return 13;
}
void input(unsigned int func) {
unsigned char temp = (char)func;
char front = temp >> 4;
char rear = temp & 0x0f;
//printf("%d", front-1);
printf("in:\n");
//setbuf(stdin, NULL);
//printf("%c\n", ch);
short in;
//setbuf(stdin, NULL);
//char ch;
//scanf("%c", &ch);
scanf("%hd", &in);
getchar();
ax[front-1] = in;
}
void output(unsigned int func) {
unsigned char temp = (char)func;
char front = temp >> 4;
char rear = temp & 0x0f;
printf("out:%hd\n", ax[front-1]);
}
void mov(unsigned int func, short imm) {
unsigned char temp = (char)func;
char front = temp >> 4;
char rear = temp & 0x0f;
if(rear == 0) {
printf("front = %d\n", front-1);
ax[front-1] = imm;
}
else if(rear >= (char)5) { // 前寄存器,后内存
ax[front-1] = 0;
ax[front-1] |= ram[ax[rear-1]+1];
ax[front-1] = ax[front-1] << 8;
ax[front-1] |= ram[ax[rear-1]];
}
else { // 前内存,后寄存器
ram[ax[front-1]] = (char)ax[rear-1];
//printf("Mov1:%d\n", ram[ax[front-1]]);
short temp = ax[rear-1];
temp = temp >> 8;
ram[ax[front-1]+1] = (char)temp;
//printf("Mov2:%d\n", ram[ax[front-1]+1]);
}
}
void add(unsigned int func, short imm) {
unsigned char temp = (char)func;
char front = temp >> 4;
char rear = temp & 0x0f;
if(rear == 0) {
ax[front-1] += imm;
}
else if(rear >= (char)5) { // 前寄存器,后内存
short t = 0;
t |= ram[ax[rear-1]+1];
t = ax[front-1] << 8;
t |= ram[ax[rear-1]];
ax[front-1] += t;
}
else { // 前内存,后寄存器
short t2 = 0;
t2 |= ram[ax[rear-1]+1];
t2 = ax[front-1] << 8;
t2 |= ram[ax[rear-1]];
t2 += ax[rear-1];
ram[ax[front-1]] = (char)t2;
//printf("Mov1:%d\n", ram[ax[front-1]]);
t2 = t2 >> 8;
ram[ax[front-1]+1] = (char)t2;
//printf("Mov2:%d\n", ram[ax[front-1]+1]);
}
}
void sub(unsigned short func, short imm) {
unsigned char temp = (char)func;
char front = temp >> 4;
char rear = temp & 0x0f;
if(rear == 0) {
ax[front-1] -= imm;
}
else if(rear >= (char)5) { // 前寄存器,后内存
short t = 0;
t |= ram[ax[rear-1]+1];
t = ax[front-1] << 8;
t |= ram[ax[rear-1]];
ax[front-1] -= t;
}
else { // 前内存,后寄存器
short t2 = 0;
t2 |= ram[ax[rear-1]+1];
t2 = ax[front-1] << 8;
t2 |= ram[ax[rear-1]];
t2 -= ax[rear-1];
ram[ax[front-1]] = (char)t2;
//printf("Mov1:%d\n", ram[ax[front-1]]);
t2 = t2 >> 8;
ram[ax[front-1]+1] = (char)t2;
//printf("Mov2:%d\n", ram[ax[front-1]+1]);
}
}
void mul(unsigned short func, short imm) {
unsigned char temp = (char)func;
char front = temp >> 4;
char rear = temp & 0x0f;
if(rear == 0) {
ax[front-1] *= imm;
}
else if(rear >= (char)5) { // 前寄存器,后内存
short t = 0;
t |= ram[ax[rear-1]+1];
t = ax[front-1] << 8;
t |= ram[ax[rear-1]];
ax[front-1] *= t;
}
else { // 前内存,后寄存器
short t2 = 0;
t2 |= ram[ax[rear-1]+1];
t2 = ax[front-1] << 8;
t2 |= ram[ax[rear-1]];
t2 *= ax[rear-1];
ram[ax[front-1]] = (char)t2;
//printf("Mov1:%d\n", ram[ax[front-1]]);
t2 = t2 >> 8;
ram[ax[front-1]+1] = (char)t2;
//printf("Mov2:%d\n", ram[ax[front-1]+1]);
}
}
void mydiv(unsigned short func, short imm) {
unsigned char temp = (char)func;
char front = temp >> 4;
char rear = temp & 0x0f;
if(rear == 0) {
ax[front-1] /= imm;
}
else if(rear >= (char)5) { // 前寄存器,后内存
short t = 0;
t |= ram[ax[rear-1]+1];
t = ax[front-1] << 8;
t |= ram[ax[rear-1]];
ax[front-1] /= t;
}
else { // 前内存,后寄存器
short t2 = 0;
t2 |= ram[ax[rear-1]+1];
t2 = ax[front-1] << 8;
t2 |= ram[ax[rear-1]];
t2 /= ax[rear-1];
ram[ax[front-1]] = (char)t2;
//printf("Mov1:%d\n", ram[ax[front-1]]);
t2 = t2 >> 8;
ram[ax[front-1]+1] = (char)t2;
//printf("Mov2:%d\n", ram[ax[front-1]+1]);
}
}
void and(unsigned short func, short imm) {
unsigned char temp = (unsigned char)func;
char front = temp >> 4;
char rear = temp & 0x0f;
if(rear == 0) {
ax[front-1] &= imm;
}
else if(rear >= (char)5) { // 前寄存器,后内存
short t = 0;
t |= ram[ax[rear-1]+1];
t = ax[front-1] << 8;
t |= ram[ax[rear-1]];
ax[front-1] &= t;
}
else { // 前内存,后寄存器
short t2 = 0;
t2 |= ram[ax[rear-1]+1];
t2 = ax[front-1] << 8;
t2 |= ram[ax[rear-1]];
t2 &= ax[rear-1];
ram[ax[front-1]] = (char)t2;
//printf("Mov1:%d\n", ram[ax[front-1]]);
t2 = t2 >> 8;
ram[ax[front-1]+1] = (char)t2;
//printf("Mov2:%d\n", ram[ax[front-1]+1]);
}
}
void or(unsigned short func, short imm) {
unsigned char temp = (char)func;
char front = temp >> 4;
char rear = temp & 0x0f;
if(rear == 0) {
ax[front-1] |= imm;
}
else if(rear >= (char)5) { // 前寄存器,后内存
short t = 0;
t |= ram[ax[rear-1]+1];
t = ax[front-1] << 8;
t |= ram[ax[rear-1]];
ax[front-1] |= t;
}
else { // 前内存,后寄存器
short t2 = 0;
t2 |= ram[ax[rear-1]+1];
t2 = ax[front-1] << 8;
t2 |= ram[ax[rear-1]];
t2 |= ax[rear-1];
ram[ax[front-1]] = (char)t2;
//printf("Mov1:%d\n", ram[ax[front-1]]);
t2 = t2 >> 8;
ram[ax[front-1]+1] = (char)t2;
//printf("Mov2:%d\n", ram[ax[front-1]+1]);
}
}
void not(unsigned short func) {
unsigned char temp = (char)func;
char front = temp >> 4;
char rear = temp & 0x0f;
if(rear == 0) {
ax[front-1] = !!(~ax[front-1]);
}
else if(rear >= (char)5) { // 前寄存器,后内存
short t = 0;
t |= ram[ax[rear-1]+1];
t = ax[front-1] << 8;
t |= ram[ax[rear-1]];
t = ~t;
ram[ax[rear-1]] = (char)t;
t = t >> 8;
ram[ax[rear-1]+1] = (char)t;
}
else {
printf("error!");
exit(1);
}
}
void cmp(unsigned short func, short imm) {
unsigned char temp = (char)func;
char front = temp >> 4;
char rear = temp & 0x0f;
printf("imm=%d\n", imm);
if(rear == 0) {
if(ax[front-1] > imm)
flag = 1;
else if(ax[front-1] == imm)
flag = 0;
else
flag = -1;
}
else { // 前寄存器,后内存
short t = 0;
t |= ram[ax[rear-1]+1];
//printf("1=%x\n",ram[ax[rear-1]+1]);
t = t << 8;
t |= ram[ax[rear-1]];
//printf("2=%x\n", ram[ax[rear-1]]);
//printf("t:%d\n", t);
if(ax[front-1] > t)
flag = 1;
else if(ax[front-1] == t)
flag = 0;
else
flag = -1;
}
}
void jmp(unsigned short func, short imm) {
imm -= 4;
if(func == 0x00) {
//printf("ip = %d\n", ip);
ip += imm;
//printf("imm = %d\n", imm);
}
else if(func == 0x01) {
if(flag == 0)
ip += imm;
}
else if(func == 0x02) {
if(flag == 1)
ip += imm;
}
else {
if(flag == -1)
ip += imm;
}
}
void halt() {
show_cpu_state();
show_ram_state();
exit(1);
}
//函数功能:执行指令
//输入:控制信号
//输出:
void execute_instrument(int ctrl) {
unsigned int func = ir;
//printf("func1=%02x\n", func);
func = func >> 16;
//printf("func1=%02x\n", func);
func = func & 0x00ff;
short imm = (short)ir;
printf("func=%02x\n", func);
switch(ctrl) {
case 0: {
//printf("finish!");
halt();
}
case 1: {
//printf("\nmov");
mov(func, imm);
break;
}
case 2: {
//printf("\nadd");
add(func, imm);
break;
}/*
case 3: {
printf("\nsub");
sub(func);
break;
}
case 4: {
printf("\nmul");
mul(func);
break;
}
case 5: {
printf("\ndiv");
mydiv(func);
break;
}
case 6: {
printf("\nand");
and(func);
break;
}
case 7: {
printf("\nor");
or(func);
break;
}
case 8: {
printf("\nnot");
not(func);
break;
}*/
case 9: {
//printf("\ncmp");
cmp(func, imm);
break;
}
case 10: {
//printf("\njmp");
jmp(func, imm);
break;
}
case 11: {
input(func);
break;
}
case 12: {
output(func);
break;
}
}
}
//函数功能:
int main(int argc, char *argv[]) {
reset();
instructions_loading(argv[1]);
printf("instructions_loading done!\n");
//show_cpu_state();
//show_ram_state();
int i = 0;
while(1) {
i++;
//printf("%d:\n", i);
//if(i == 24) // jmp写完了,从jmp下一条开始
// break;
load_instruction();
inc_ip();
//show_cpu_state();
int ctrl = decode();
printf("ctrl = %d\n", ctrl);
execute_instrument(ctrl);
show_cpu_state();
show_ram_state();
}
//show_cpu_state();
//show_ram_state();
return 0;
}
10-22
473
12-26
1952
11-08
7359