【问题标题】:How do I write a macro that conditionally updates an emulators CPU flags?如何编写有条件地更新模拟器 CPU 标志的宏?
【发布时间】:2017-10-15 14:18:59
【问题描述】:

我正在使用 Rust 编写一个 6502 CPU 模拟器,并且我正在尝试使我的代码尽可能 DRY。

解码操作码并执行的代码如下:

//self refers to CPU struct

match opcode {
    0x29 => {self.A &= self.imm(); update_flags!(self.cpu, "Z0", "N7");},
    // ... other 55 opcodes
}

我想要一种在执行每条指令后更新 CPU 标志的简单方法。例如,执行 AND 指令后,如果 A = 0,则设置标志 Z,如果第 7 位为 1,则设置标志 N。我可以将这两个条件描述为 Z0 和 N7。

我需要编写一个宏,它将 CPU 结构、Z0 和 N7 作为参数并扩展为:

if self.A == 0 {set flag Z};
if self.A.7thbit == 1 {set flag N};

这可能吗?

【问题讨论】:

  • 为什么必须是宏?使用名为 Z 和“N”的函数会有什么问题,例如fn Z(&mut self, value: u8) { self.z_flag = self.A == 0; }` 和fn N(&mut self, bit: u8) { self.n_flag = self.A & (1u8 << bit) != 0; } 然后您可以将它们称为self.Z(0); self.N(7);。当使用常量参数调用时,它们应该和宏一样高效。
  • 是的,我会适当地使用函数。最后,它们更容易调试。
  • 我现在已经发布了以上内容作为答案。

标签: macros rust


【解决方案1】:

这里不需要宏,因为函数可以实现同等(如果不是更好)的人体工程学和效率。

例如,您可以定义如下方法:

fn Z(&mut self, value: u8) {
    self.z_flag = self.A == value;
}

fn N(&mut self, bit: u8) {
    self.n_flag = self.A & (1u8 << bit) != 0;
}

你可以写self.Z(0); self.N(7);,而不是update_flags!(self.cpu, "Z0", "N7");。当使用常量参数调用时,它们应该和宏一样高效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-30
    • 1970-01-01
    • 2019-11-11
    • 2011-08-07
    • 2018-11-21
    • 2018-06-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多