assembly - 将寄存器加载到自身的指令的目的是什么?

标签 assembly memory emulation z80 gameboy

在查看 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,不知道我是否完美地破译了它。

人们还期望 76LD (HL),(HL),这比 LD A,A 更没有意义>,所以有特殊的逻辑可以捕捉到那个并执行 HALT

所以它是关于指令解码器的简单性,使用相同的位模式来选择源/目标寄存器,并且关于不添加更多晶体管来捕获 same,same 情况,除了 ( HL),(HL)(这可能会在需要内存访问的源和目标上都发生内部故障,因此在硬件设计中额外的“逻辑”可能相当简单。

请记住,早期的 CPU 通常是手工设计的,晶体管的总数量必须保持在较低水平,既要适合芯片,又要便于手工绘制电路并验证其正确性。

编辑:Z80 有大约 8500 个晶体管,您可能需要检查:https://en.wikipedia.org/wiki/Transistor_counthttps://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/

相关文章:

assembly - 尝试获取内存访问模式统计信息时如何处理虚拟地址?

C代码翻译成MIPS

寄存器变量的概念(数据类型:register) in C language?

python - 为 PyTorch 使用大数据集的最有效方法?

c - 函数指针与宏与内联

通过平面 assembly 中的过程对列表进行排序

c - GNU 汇编程序的输出目标文件格式是什么?

hadoop - 为什么Reducer比映射器获得更多的内存?

azure - 同步失败: access denied to azure compute emulator

android - Appcelerator Titanium 错误 : Application Installer abnormal process termination. 进程退出值为 1