8 位指令集架构是否需要两字节指令?
Are two-byte instructions necessary for an 8-bit instruction set architecture?
我正在设计和实现一个简单的 8 位计算机。我打算有一个 8 位数据总线,8 位地址总线和 8 位指令。我打算有一个 RISC 风格的加载存储架构。我正在设计指令集,并试图确定是否有可能只使用 8 位指令(意味着没有多字节指令)。
如果一条指令是 8 位的,那么其中一些位字段将被操作码占用,其余的可能被要处理的数据表示占用。例如,考虑一个 load immediate
指令,它获取一个地址并将该地址处的内存内容加载到 CPU 中的特定寄存器中。由于立即加载指令的操作码将占用几个位,因此指令中没有空间容纳完整的 8 位地址。例如,如果此指令的操作码是二进制的“11”,则只有 6 位保留用于加载的地址。
在我看来,唯一的选择是将 immediate
类型指令扩展为两个字节,其中第一个包含操作码,第二个包含立即值。还有另一种方法吗?或许还有其他技巧?
Are two-byte instructions necessary for an 8-bit instruction set architecture?
不,2 字节指令不是绝对必要的。然而,如果没有 2 字节指令,您需要更多指令才能完成相同的工作。
例如,如果您不能执行“mov r1,0x9F
”(将 8 位值加载到 r1
),因为这需要一个操作码加上一个 8 位立即值,那么您可以通过将多个较小的立即值与类似以下的序列连接在一起来解决它:
mov r1,0x9 ;4-bit opcode, 4-bit immediate, r1 = 0x09
shl r1,4 ;4-bit opcode, 4-bit immediate, r1 = 0x90
or r1,0x0F ;4-bit opcode, 4-bit immediate; r1 = 0x9F
当然这很糟糕(与 2 字节指令相比,指令数量增加了 3 倍,代码大小增加了 50%)。
还有其他方法可以解决此问题。
一种替代方法是将 "load immediate and shift left by 4" 放入一条指令中,或者将 "load high bits with immediate" 和 "load low bits with immediate" 指令放入其中,因此上面的示例可能会变成:
load_high_bits r1,0x9 ;4-bit opcode, 4-bit immediate, r1 = 0x09
load_low_bits r1,0x0F ;4-bit opcode, 4-bit immediate; r1 = 0x9F
另一种选择是拥有一个可以用较小地址访问的常量池。例如,如果您有一个采用 4 位立即值的 "load constant" 指令,那么您可以在内存中存储 16 个(8 位)常量并用 load r1, [4_bit_offset]
之类的东西加载它们。您还可以使用(隐含的?)基址寄存器来允许常量池位于任何地址(因此您可以从地址“8 位基址寄存器 + 4 位偏移量”加载常量),例如“load r1,[r2 + 4_bit_offset]
".
我正在设计和实现一个简单的 8 位计算机。我打算有一个 8 位数据总线,8 位地址总线和 8 位指令。我打算有一个 RISC 风格的加载存储架构。我正在设计指令集,并试图确定是否有可能只使用 8 位指令(意味着没有多字节指令)。
如果一条指令是 8 位的,那么其中一些位字段将被操作码占用,其余的可能被要处理的数据表示占用。例如,考虑一个 load immediate
指令,它获取一个地址并将该地址处的内存内容加载到 CPU 中的特定寄存器中。由于立即加载指令的操作码将占用几个位,因此指令中没有空间容纳完整的 8 位地址。例如,如果此指令的操作码是二进制的“11”,则只有 6 位保留用于加载的地址。
在我看来,唯一的选择是将 immediate
类型指令扩展为两个字节,其中第一个包含操作码,第二个包含立即值。还有另一种方法吗?或许还有其他技巧?
Are two-byte instructions necessary for an 8-bit instruction set architecture?
不,2 字节指令不是绝对必要的。然而,如果没有 2 字节指令,您需要更多指令才能完成相同的工作。
例如,如果您不能执行“mov r1,0x9F
”(将 8 位值加载到 r1
),因为这需要一个操作码加上一个 8 位立即值,那么您可以通过将多个较小的立即值与类似以下的序列连接在一起来解决它:
mov r1,0x9 ;4-bit opcode, 4-bit immediate, r1 = 0x09
shl r1,4 ;4-bit opcode, 4-bit immediate, r1 = 0x90
or r1,0x0F ;4-bit opcode, 4-bit immediate; r1 = 0x9F
当然这很糟糕(与 2 字节指令相比,指令数量增加了 3 倍,代码大小增加了 50%)。
还有其他方法可以解决此问题。
一种替代方法是将 "load immediate and shift left by 4" 放入一条指令中,或者将 "load high bits with immediate" 和 "load low bits with immediate" 指令放入其中,因此上面的示例可能会变成:
load_high_bits r1,0x9 ;4-bit opcode, 4-bit immediate, r1 = 0x09
load_low_bits r1,0x0F ;4-bit opcode, 4-bit immediate; r1 = 0x9F
另一种选择是拥有一个可以用较小地址访问的常量池。例如,如果您有一个采用 4 位立即值的 "load constant" 指令,那么您可以在内存中存储 16 个(8 位)常量并用 load r1, [4_bit_offset]
之类的东西加载它们。您还可以使用(隐含的?)基址寄存器来允许常量池位于任何地址(因此您可以从地址“8 位基址寄存器 + 4 位偏移量”加载常量),例如“load r1,[r2 + 4_bit_offset]
".