我正在将 NMOS6502 仿真器重构为多个类。我想知道是否有一种“面向对象”的方式来定义函数跳转表。基本上,我已经定义了单独的指令类来对相关的 cpu 操作组进行分类——比如“CStackInstHandler”或“CArithmeticInstHandler”,它们将引用一个 cpu 对象。每个指令类都派生自一个抽象指令类。每个派生指令类都有一组函数,它们将使用 cpu 对象的公共接口来改变 cpu 状态,例如:
uint8_t opcode = _memory->readMem(_cpu->getProgramCounter());
AInstructionHandler* _handler = _cpu->getInstHandler(opcode);
_handler->setCpu(&cpu);
_handler->setMemory(&memory);
_handler->execute(opcode);
问题是在运行时指令处理程序以及为该处理程序定义的适当成员函数需要使用操作码来确定。
所以我们有 - 从内存中读取操作码,cpu 使用一个表将操作码映射到指令处理程序类型,然后指令处理程序使用相同的操作码来选择正确的函数。每条指令都会覆盖一个“执行”功能,例如:
void CBranchInstHandler::execute() {
switch(_opcode) {
case 0x90:
this->BCC();
break;
case 0xb0:
this->BCS();
break;
case 0xf0:
this->BEQ();
break;
case 0x30:
this->BMI();
break;
case 0xd0:
this->BNE();
break;
case 0x10:
this->BPL();
break;
default:
break;
}
}
void CBranchInstHandler::BCC() {
uint16_t address = this->getAddress();
if(!_cpu->isCarry()) {
uint16_t pc = _cpu->getPC();
pc += address;
_cpu->setPC(pc);
}
}
/*more instruction specific functions...*/
我最终得到了两个查找,其中一个是多余的。一个选择处理程序,另一个选择处理程序函数。我觉得这是完成这项任务的错误方法,但我不确定是否有一种替代方法不仅会演变为非成员函数组。
我想知道是否有人对这个问题有深入的了解。它基本上归结为想要将一个类重构为更小的部分(具有指令成员函数的 cpu 类重构为 cpu 类和指令类),但是所有组件都如此相互关联,以至于我最终不得不重复自己。引入了冗余。
一个非面向对象的解决方案是让这些指令成为接受 cpu 引用的非成员函数。然后,将定义一个函数跳转表,指令将被操作码查找和索引并执行。
对于对象,这似乎并不实际。我可以将所有指令设为静态或其他东西,但这似乎没有抓住重点。
任何有关甚至切向相关问题的见解或信息都会非常有帮助。
谢谢。