C++ 如何找到递增指令指针的机器代码指令末尾
所以我正在制作一个模拟器,目前我正在制作一个小型虚拟CPU。有了我的代码,我的CPU就可以很好地运行自定义指令了——但我的操作方式很不规范。在正常环境中,计算机如何处理单个机器代码操作 我知道每个操作只有一个操作码,硬件本身会增加指令指针吗?或者CPU是否以不同的方式递增指令指针?如果CPU增加指令指针,它如何知道要移动多少字节,是否以某种方式从操作码获取数据 如果这是个愚蠢的问题,我很抱歉。我没有我需要的经验,我只是没有找到任何资源来回答这个问题 这是我正在使用的小CPU,我跳过了RAM类和指令类,RAM类基本上只是一个连续的内存块,指令类中只有一个函数指针(我确定这不是最快的方法,但我正在学习)C++ 如何找到递增指令指针的机器代码指令末尾,c++,emulation,machine-code,C++,Emulation,Machine Code,所以我正在制作一个模拟器,目前我正在制作一个小型虚拟CPU。有了我的代码,我的CPU就可以很好地运行自定义指令了——但我的操作方式很不规范。在正常环境中,计算机如何处理单个机器代码操作 我知道每个操作只有一个操作码,硬件本身会增加指令指针吗?或者CPU是否以不同的方式递增指令指针?如果CPU增加指令指针,它如何知道要移动多少字节,是否以某种方式从操作码获取数据 如果这是个愚蠢的问题,我很抱歉。我没有我需要的经验,我只是没有找到任何资源来回答这个问题 这是我正在使用的小CPU,我跳过了RAM类和指
const int REGNUM=8;
类cpu{
受保护的:
ui16 reg[REGNUM];//寄存器是否应更改为联合?
ram*pram;//指向ram的管道指针
矢量插件;
指令itable[255];//如果超过255条指令,则可以生成向量
字节inum;//itable中的当前指令数,在添加指令时递增
公众:
cpu();
//~cpu();
void connect_ram(ram*inram);//重置指令指针
void connect_module(module*addon);//从硬盘到屏幕的任何东西
ram*getram();
字节加法指令(常量指令和ins);
void setreg(ui8 which,ui16 val);
ui16 getreg(ui8 which);
void exe();//运行执行单元,增量指令指针
};
cpu::cpu(){
inum=0;
pram=NULL;
对于(int a=0;agetram())[c->getreg(7)+1];//下一个字节
ins=ins getram())[c->getreg(7)+2];//下一个字节
c->setreg(7,ins);
}
无效输出(cpu*c){//输出第一个寄存器
coutgetreg(0);
c->setreg(7,c->getreg(7)+1);
}
无效getram(cpu*c){
ui16ad=((ui16)(*c->getram())[c->getreg(7)+1])getreg(7)+2];
c->setreg(0,(*c->getram())[ad]);//将寄存器1设置为地址的值
c->setreg(7,c->getreg(7)+3);//移动指令指针
}
无效设置RAM(cpu*c){
ui16ad=((ui16)(*c->getram())[c->getreg(7)+1])getreg(7)+2];//要更改的地址
(*c->getram())[ad]=c->getreg(0);//将地址处的字节设置为第一个寄存器中的值
c->setreg(7,c->getreg(7)+3);//移动指令指针
}
无效增量(cpu*c){
c->setreg(0,c->getreg(0)+1);
c->setreg(7,c->getreg(7)+1);
}
无效减量(cpu*c){
c->setreg(0,c->getreg(0)-1);
c->setreg(7,c->getreg(7)+3);
}
无效nop(cpu*c){
c->setreg(7,c->getreg(7)+1);//移动指令指针
}
在解释器中,每条指令在提取其操作数的过程中都会找到自己的端点。指令本身的初始提取和它自己的所有提取都会增加PC,因此PC总是指向下一个要提取的对象
硬件是如何实现的并不重要。你不是在写硬件。哦,这很有帮助!所以当我需要下一部分内存时,我应该调用一个fetch,而不是仅仅手动获取它-这比我的方法更有意义。不知道我在想什么,谢谢!:D
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
}