class Processor {
// ...
void executeOpcode(Opcode opcode) {
switch (opcode) {
// ...
case LD_A_B:
A = B;
break;
case LD_A_C:
A = C;
break;
case LD_A_D:
A = D;
break;
// ...
}
}
// ...
}
Opcode
typedef enum
,每个指令的名称与其1字节opcode相对应。在此示例中,有一系列指令执行相同的操作,但使用不同的寄存器。这种模式发生在许多不同的指令中,有些执行更复杂的操作不仅仅是简单的副本。
我要问的是:有一种方法可以编程为处理器的所有寄存器编写开关条款吗?
到目前为止我尝试了什么我知道我可以实现这样的一系列功能:
void Processor::LD_x_y(Register& x, Register y) { x = y };
开关变为:
switch (opcode) {
// ...
case LD_A_B:
LD_x_y(A, B);
break;
case LD_A_C:
LD_x_y(A, C):
break;
//...
}
但是重复此模式以进行许多说明会使我遇到以下错误:
switch (opcode) {
// ...
case LD_A_B:
LD_x_y(A, B);
break;
case LD_A_C:
LD_x_y(A, B): // <-- forgot to change the register in the function call!
break;
//...
}
我对使用预处理器指令并不熟悉,但我知道我应该能够按照以下方式写一些内容。
#define EXPAND_LD_x_y(X, Y) case LD_X_Y: X=Y; break;
// ...
switch (opcode) {
// ...
EXPAND_LD_x_y(A, B)
EXPAND_LD_x_y(A, C)
//...
}
bottomline我认为,最后一种方法足够好,但是我真的很想拥有一些自动化的东西,以扩大每种寄存器组合的开关案例。
有一种方法可以使用预处理器指令做到这一点?
instead
switch
std::map<
Opcode,
std::function<void()>
> instruction = {
{LD_A_B, [&A,&B](){ A = B; }},
{LD_A_C, [&A,&C](){ A = C; }}
//...
};
这里的想法是,由于每个指令基本上都知道该怎么做,因此我们让指令决定从哪里获取资源,而不是通过它们作为参数传递。