所以我正在制作模拟器,我目前正在制作一个小型虚拟CPU。使用我的代码,我的CPU将运行自定义指令就好 - 但我正在做的方式是hacky。在正常环境中,计算机如何处理单个机器代码操作?
我知道每次操作都有一个操作码,硬件本身是否会增加指令指针?或者CPU是否以不同的方式递增指令指针?如果CPU递增指令指针,它如何知道要移动多少字节,它是否以某种方式从操作码中获取数据?
如果这看起来像个愚蠢的问题,我很抱歉。我没有我需要的经验,我只是找不到任何能回答这个问题的资源。
这是我正在研究的小CPU,我跳过了RAM类和指令类,ram类基本上只是一个连续的内存块,而且指令类中只有一个函数指针(不是最快的方法) “当然,但我正在学习)
const int REGNUM = 8;
class cpu{
protected:
ui16 reg[REGNUM];//registers should change to unions?
ram* pram;//pipeline pointer to ram
vector<module*> addons;
instruction itable[255];//can make vector if more than 255 instructions
byte inum; //current number of instructions in the itable, increments when instruction added
public:
cpu();
//~cpu();
void connect_ram(ram* inram);//reset instruction pointer
void connect_module(module* addon); //anything from a hard drive to a screen
ram* getram();
byte add_instruction(const instruction& ins);
void setreg(ui8 which, ui16 val);
ui16 getreg(ui8 which);
void exe(); //run execution unit, increment instruction pointer
};
cpu::cpu(){
inum=0;
pram=NULL;
for(int a = 0; a<REGNUM; a++){
reg[a]=0;
}
}
void cpu::connect_ram(ram* inram){
pram=inram;
reg[7]=0;
}
void cpu::connect_module(module* addon){
addons.push_back(addon);
}
ram* cpu::getram(){
return pram;
}
void cpu::setreg(ui8 which, ui16 val){
reg[which]=val;
}
ui16 cpu::getreg(ui8 which){
return reg[which];
}
void cpu::exe(){
itable[(*getram())[getreg(7)]].func(this);
}
byte cpu::add_instruction(const instruction& ins){
itable[inum]=ins;
inum++;
return inum-1; //return table num of instruction
}
void jmp(cpu* c){ //can depend on architecture, 16 bit jump different than 8 bit?
ui16 ins = (*c->getram())[c->getreg(7) + 1];//next byte
ins = ins << 8;
ins += (*c->getram())[c->getreg(7) + 2];//second next byte
c->setreg(7,ins);
}
void output(cpu* c){ //outputs the first register
cout << (char)c->getreg(0);
c->setreg(7,c->getreg(7)+1);
}
void getram(cpu* c){
ui16 ad = (((ui16)(*c->getram())[c->getreg(7) + 1])<<8)+(ui16)(*c->getram())[c->getreg(7)+2];
c->setreg(0,(*c->getram())[ad]); //set register 1 to the value of the address
c->setreg(7,c->getreg(7)+3); //move instruction pointer
}
void setram(cpu* c){
ui16 ad = (((ui16)(*c->getram())[c->getreg(7) + 1])<<8)+(ui16)(*c->getram())[c->getreg(7)+2]; //address to change
(*c->getram())[ad] = c->getreg(0); //set byte at address to value in first register
c->setreg(7,c->getreg(7)+3); //move instruction pointer
}
void increg(cpu* c){
c->setreg(0,c->getreg(0)+1);
c->setreg(7,c->getreg(7)+1);
}
void decreg(cpu* c){
c->setreg(0,c->getreg(0)-1);
c->setreg(7,c->getreg(7)+3);
}
void nop(cpu* c){
c->setreg(7,c->getreg(7)+1); //move instruction pointer
}
答案 0 :(得分:2)
在解释器中,每个指令在获取其操作数的过程中找到自己的结束。初始获取指令本身及其自己的所有读取都会增加PC,因此PC始终指向下一个要获取的内容。
它在硬件中的完成方式并不相关。你不是在写硬件。