Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何找到递增指令指针的机器代码指令末尾_C++_Emulation_Machine Code - Fatal编程技术网

C++ 如何找到递增指令指针的机器代码指令末尾

C++ 如何找到递增指令指针的机器代码指令末尾,c++,emulation,machine-code,C++,Emulation,Machine Code,所以我正在制作一个模拟器,目前我正在制作一个小型虚拟CPU。有了我的代码,我的CPU就可以很好地运行自定义指令了——但我的操作方式很不规范。在正常环境中,计算机如何处理单个机器代码操作 我知道每个操作只有一个操作码,硬件本身会增加指令指针吗?或者CPU是否以不同的方式递增指令指针?如果CPU增加指令指针,它如何知道要移动多少字节,是否以某种方式从操作码获取数据 如果这是个愚蠢的问题,我很抱歉。我没有我需要的经验,我只是没有找到任何资源来回答这个问题 这是我正在使用的小CPU,我跳过了RAM类和指

所以我正在制作一个模拟器,目前我正在制作一个小型虚拟CPU。有了我的代码,我的CPU就可以很好地运行自定义指令了——但我的操作方式很不规范。在正常环境中,计算机如何处理单个机器代码操作

我知道每个操作只有一个操作码,硬件本身会增加指令指针吗?或者CPU是否以不同的方式递增指令指针?如果CPU增加指令指针,它如何知道要移动多少字节,是否以某种方式从操作码获取数据

如果这是个愚蠢的问题,我很抱歉。我没有我需要的经验,我只是没有找到任何资源来回答这个问题

这是我正在使用的小CPU,我跳过了RAM类和指令类,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
}