【发布时间】:2019-01-27 23:22:03
【问题描述】:
我有一个枚举,它代表 8080 处理器上所有可能的指令。一条指令可以是 1、2 或 3 个字节长,这取决于它是否有与之相关的信息以及有多少。例如:
#[allow(non_camel_case_types)]
enum Instruction {
None,
NOP,
LXI_B_D16(u8, u8),
STAX_B,
INX_B,
MVI_B_D8(u8),
MVI_C_D8(u8),
RRC,
LXI_D_D16(u8, u8),
MVI_D_D8(u8),
RAL,
DCR_E,
MVI_E_D8(u8),
LXI_H_D16(u8, u8),
SHLD(u16),
LHLD(u16),
// ...
}
在为指令分配内存地址时,我在二进制文件中逐条指令迭代,使用每条指令的长度来确保我的循环不会在指令中途着陆并给我垃圾。我用一个巨大的匹配表达式来做到这一点,它返回一个包含正确指令及其长度的元组:
match value {
0x00 => (Instruction::NOP, 1),
0x01 => (Instruction::LXI_B_D16(d1, d2), 3),
0x02 => (Instruction::STAX_B, 1),
0x05 => (Instruction::DCR_B, 1),
0x06 => (Instruction::MVI_B_D8(d1), 2),
0x07 => (Instruction::RLC, 1),
0x0e => (Instruction::MVI_C_D8(d1), 2),
0x0f => (Instruction::RRC, 1),
0x11 => (Instruction::LXI_D_D16(d1, d2), 3),
0x19 => (Instruction::DAD_D, 1),
// ...
}
这很难看,但我不想将这个长度数字与类型相关联,因为它真的只在我解析文件时才重要。
似乎我应该能够从变体的形状推断出指令的长度。不带参数的长度为 1,带一个 u8 参数的长度为 2,带一个 u16 或两个 u8 参数的长度为 3。
我无法弄清楚如何以编程方式获得这种形状。例如,我不能像数组或向量那样调用len()。
我不认为这是 How to get the number of elements in an enum as a constant value? 的副本,因为我不是在寻找一种方法来获取枚举中的变体数量,而是任何单个变体的参数数量.
【问题讨论】:
-
我不认为这是可能的,我也想知道你在用这些信息做什么。你不应该需要这个。
-
似乎潜在的问题更多是关于消除重复。在 Rust 中做到这一点的一种方法是使用宏。您可以使用宏在生成大匹配表达式的同时生成指令枚举。
-
@stargateur 一个 8080 ROM(在我的例子中是 Space Invaders)作为单个 u8 数组读入我的程序。每条指令的长度为 1、2 或 3 个 u8:第一个 u8 表示指令类型,其余字节是相关数据。例如,一个 JMP 命令有一个关联的 u16 内存地址来标记跳转位置。当我解析这个数组时,我按指令字节进行迭代,所以我需要知道指令的长度才能知道指针增加多少。这可能是一种非常幼稚的做法,我不确定!