Как найти в конце инструкции машинного кода, чтобы увеличить указатель инструкции

Так что я нахожусь на пути к созданию эмулятора, и в настоящее время я делаю небольшой виртуальный процессор. С кодом, который у меня есть, мой процессор будет выполнять пользовательские инструкции просто отлично, но способ, которым я это делаю, является хакерским. Как в обычном окружении компьютер обрабатывает одну машинную операцию?

Я понимаю, что наличие одного кода операции на операцию аппаратные средства сам приращивать указатель инструкции? Или процессор увеличивает указатель инструкции другим способом? Если процессор увеличивает указатель инструкции, как он узнает, сколько байтов нужно переместить, получает ли он данные из кода операции?

Извините, если это кажется глупым вопросом. У меня нет опыта, в котором я нуждаюсь, и я просто не нахожу ресурсов, которые отвечают на этот вопрос.

Вот небольшой процессор, над которым я работаю, я пропустил класс 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

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector