在查看 Gameboy 的指令集时,我遇到了如下指令:
LD A, A
LD B, B
LD C, C
LD D, D
...
每条指令在this table 中都有自己的操作码。 ,这让我觉得由于可能的操作码数量的限制,它们有些重要。
我首先认为它可能会取消引用该寄存器中的指针并将值存储在该指针( like in this question )中,但在 emulator 中, LD A, A
实现为:
Z80._r.a = Z80._r.a
它们似乎对处理器的状态没有影响(只是将寄存器设置为它们自己的值),并且与 NOP
执行相同的周期数。
为什么将这些操作码包含在指令集中以及它们的用途是什么?
最佳答案
他们简化了解码单元,如果你愿意检查的话
7F LD A,A
78 LD A,B
79 LD A,C
对
47 LD B,A
40 LD B,B
41 LD B,C
对
4F LD C,A
48 LD C,B
49 LD C,C
你可以注意到,低 3 位是为源寄存器保留的(值 0-7 去 B,C,D,E,H,L,(HL),A
),3它们旁边的位是目标寄存器,同样具有相同的 0-7 含义(因此 0 与 0 创建 LD B,B
),而前两位 01
选择LD
,不知道我是否完美地破译了它。
人们还期望 76
是 LD (HL),(HL)
,这比 LD A,A
更没有意义>,所以有特殊的逻辑可以捕捉到那个并执行 HALT
。
所以它是关于指令解码器的简单性,使用相同的位模式来选择源/目标寄存器,并且关于不添加更多晶体管来捕获 same,same
情况,除了 ( HL),(HL)
(这可能会在需要内存访问的源和目标上都发生内部故障,因此在硬件设计中额外的“逻辑”可能相当简单。
请记住,早期的 CPU 通常是手工设计的,晶体管的总数量必须保持在较低水平,既要适合芯片,又要便于手工绘制电路并验证其正确性。
编辑:Z80 有大约 8500 个晶体管,您可能需要检查:https://en.wikipedia.org/wiki/Transistor_count和 https://en.wikipedia.org/wiki/Zilog_Z80 ...而且 GameBoy 对 Z80 进行了一些修改,但总晶体管的数量将非常接近原始值,虽然我没有寻找确切的值,我不确定 future 有多远任天堂正在扩展它,也许他们已经可以负担得起 20-50k 的价格,但我对此表示怀疑。
附录:最近我读到了关于俄罗斯 Sinclair ZX Spectrum 克隆的文章,它们是经过大量修改的机器,增加了额外的功率、内存和功能......其中一些正在使用这些 ld same,same
控制 DMA 传输的操作码,因此在这些机器上将它们用作 nop
的代码可能无法正确执行。这与 GameBoy 无关,但如果您有二进制目标是“Sprinter”或类似的俄罗斯 ZX 克隆之一,并且您在反汇编中发现其中之一,请不要自动考虑它们 nop
,它们可能是实际执行某些操作的有效代码的一部分(很可能是使用 DMA)。
关于assembly - 将寄存器加载到自身的指令的目的是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50187678/