加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
simulator.c 5.79 KB
一键复制 编辑 原始数据 按行查看 历史
szx 提交于 2017-12-07 17:00 . step3: update ISA.md
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include "isa.h"
unsigned char *mem; // main memory of simulator
unsigned char reg1, reg2; // used to install reg id
/*
* Func: get_reg_id
* @reg: a byte data to install regs
* @index: reg number of regs, must be 1 or 2
* return: reg id
*/
char get_reg_id(char reg, int index){
switch (index) {
case 1:
return reg >> 4;
case 2:
return reg & 0x0F;
default:
return 0xFF;
}
}
/*
* Func: cpu, execute instruction
* @pc: program counter
*/
void cpu(int pc){
int cycle = 0; // number of instruction
char mem_content[25]; // translate memory to string
while(cycle++ < 20){
switch(mem[pc]){
case 0x0: // halt
printf("\nsystem halt\n");
return;
case 0x10: // nop
pc++;
continue;
case 0x20: // rrmov %reg1, %reg2
reg1 = get_reg_id(mem[pc+1],1);
reg2 = get_reg_id(mem[pc+1],2);
reg_table[reg2].value = reg_table[reg1].value;
pc += 2;
break;
case 0x30: // irmov imme, %reg
reg2 = get_reg_id(mem[pc+1],2);
reg_table[reg2].value =(int) mem[pc+2];
pc += 6;
break;
case 0x40: // store %reg1, D(%reg2)
reg1 = get_reg_id(mem[pc+1],1);
reg2 = get_reg_id(mem[pc+1],2);
mem[reg_table[reg2].value + *(int *)mem[pc+2]] = reg_table[reg1].value;
pc += 6;
break;
case 0x50: // load D(%reg1), %reg2
reg1 = get_reg_id(mem[pc+1],1);
reg2 = get_reg_id(mem[pc+1],2);
reg_table[reg2].value = mem[reg_table[reg1].value + *(int *)mem[pc+2]];
pc += 6;
break;
case 0x60: // add %reg1, %reg2
reg1 = get_reg_id(mem[pc+1],1);
reg2 = get_reg_id(mem[pc+1],2);
reg_table[reg2].value += reg_table[reg1].value;
pc += 2;
break;
case 0x61: // sub %reg1, %reg2
reg1 = get_reg_id(mem[pc+1],1);
reg2 = get_reg_id(mem[pc+1],2);
reg_table[reg2].value -= reg_table[reg1].value;
pc += 2;
break;
case 0x62: // and %reg1, %reg2
reg1 = get_reg_id(mem[pc+1],1);
reg2 = get_reg_id(mem[pc+1],2);
reg_table[reg2].value &= reg_table[reg1].value;
pc += 2;
break;
case 0x63: // or %reg1, %reg2
reg1 = get_reg_id(mem[pc+1],1);
reg2 = get_reg_id(mem[pc+1],2);
reg_table[reg2].value |= reg_table[reg1].value;
pc += 2;
break;
case 0x64: // not %reg1, %reg2
reg1 = get_reg_id(mem[pc+1],1);
reg2 = get_reg_id(mem[pc+1],2);
reg_table[reg2].value = !reg_table[reg1].value;
pc += 2;
break;
case 0x65: // xor %reg1, %reg2
reg1 = get_reg_id(mem[pc+1],1);
reg2 = get_reg_id(mem[pc+1],2);
reg_table[reg2].value ^= reg_table[reg1].value;
pc += 2;
break;
case 0x66: // shl %reg1, %reg2
reg1 = get_reg_id(mem[pc+1],1);
reg2 = get_reg_id(mem[pc+1],2);
reg_table[reg2].value >>= reg_table[reg1].value;
pc += 2;
break;
case 0x67: // shr %reg1, %reg2
reg1 = get_reg_id(mem[pc+1],1);
reg2 = get_reg_id(mem[pc+1],2);
reg_table[reg2].value <<= reg_table[reg1].value;
pc += 2;
break;
case 0x70: // jmp Dest
pc = (int) mem[pc+1];
break;
case 0x71: // je Dest
if(reg_table[REG_FLAGS].value & 0x40) // ZF == 1
pc = (int) mem[pc+1];
break;
case 0x72: // jl Dest
if(reg_table[REG_FLAGS].value ^ 0x880) // (SF xor OF) == 1
pc = (int) mem[pc+1];
break;
case 0x73: // jg Dest
if(0 == ((reg_table[REG_FLAGS].value & 0x40) | (reg_table[REG_FLAGS].value ^ 0x880))) // ((SF xor OF) or ZF) == 0
pc = (int) mem[pc+1];
break;
case 0x74: // jne Dest
if(0 == (reg_table[REG_FLAGS].value & 0x40)) // ZF == 0
pc = (int) mem[pc+1];
break;
case 0x75: // jle Dest
if((reg_table[REG_FLAGS].value & 0x40) | (reg_table[REG_FLAGS].value ^ 0x880)) // ((SF xor OF) or ZF) == 1
pc = (int) mem[pc+1];
break;
case 0x76: // jge Dest
if(0 == (reg_table[REG_FLAGS].value ^ 0x880)) // (SF xor OF) == 0
pc = (int) mem[pc+1];
break;
case 0x80: // call Dest
pc += 5;
*(int *) mem[reg_table[REG_SP].value - 4] = pc;
reg_table[REG_SP].value -= 4;
pc = (int) mem[pc+1];
break;
case 0x90: // ret
pc = (int) mem[reg_table[REG_SP].value];
reg_table[REG_SP].value += 4;
break;
case 0xa0: // push %reg
reg1 = get_reg_id(mem[pc+1], 1);
*(int *) mem[reg_table[REG_SP].value - 4] = reg_table[reg1].value;
reg_table[REG_SP].value -= 4;
pc += 2;
break;
case 0xb0: // pop %reg
reg1 = get_reg_id(mem[pc+1], 1);
reg_table[reg1].value = (int) mem[reg_table[REG_SP].value];
reg_table[REG_SP].value += 4;
pc += 2;
break;
case 0xc0: // in imme, %reg
/* not implement */
pc += 3;
break;
case 0xd0: // out %reg, imme
if(1 == mem[pc+2]){
reg1 = get_reg_id(mem[pc+1],1);
printf("%c", (char) reg_table[reg1].value);
}
pc += 3;
break;
default:
sprintf(mem_content,"%x", mem[pc]);
printf("err: pc=%d mem=%s\n",pc, mem_content);
pc++;
}
}
}
int main(int argc, char **argv){
char *bi_fname;
FILE *bi_file;
struct stat statbuff; // used to get file length
mem = malloc(4096);
if(NULL == mem){
printf("mem alloc err!\n");
exit(0);
}
/* open binary file */
bi_fname = argv[1];
bi_file = fopen(bi_fname, "rb+");
if(bi_file == NULL){
printf("open binary file err: %s\n", bi_fname);
exit(0);
}
/* load file to mem */
stat(bi_fname, &statbuff);
if(statbuff.st_size !=fread(mem, 1, statbuff.st_size, bi_file))
printf("load file err\n");
/* run from pc=0 until HALT or cycle<20 */
cpu(0);
free(mem);
fclose(bi_file);
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化