在浏览Gameboy的指令集时,我遇到了诸如以下的说明:
LD A, A
LD B, B
LD C, C
LD D, D
...
这些指令中的每一条都在this table中拥有它自己的操作码,这让我认为由于对可能的操作码数量的限制,它们具有一定的重要性。
我首先想到它可能会取消引用该寄存器中的指针并将值存储在该指针(like in this question),但在emulator中,LD A, A
实现为:< / p>
Z80._r.a = Z80._r.a
它们似乎对处理器的状态没有影响(只是将寄存器设置为它们自己的值)并且执行与NOP
相同的周期数。
为什么这些操作码包含在指令集中,它们用于什么目的?
答案 0 :(得分:13)
如果您要检查
,它们会简化解码单元7F LD A,A
78 LD A,B
79 LD A,C
VS
47 LD B,A
40 LD B,B
41 LD B,C
VS
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 vs 0创建LD B,B
),前两位01
选择LD
,如果我完全破译它,请不要确定快速浏览。
人们还希望76
成为LD (HL),(HL)
,这比LD A,A
更有意义,所以有特殊的逻辑来捕捉那个HALT
same,same
相反。
所以关于指令解码器的简单性,使用相同的位模式选择源/目标寄存器,以及不添加更多晶体管来捕捉(HL),(HL)
情况,除了ld same,same
(这可能会在源和目标都需要内存访问的内部失败,所以可能额外的&#34;逻辑&#34;在硬件设计中相当简单。
请记住,早期的CPU通常是手工设计的,并且总晶体管的数量必须保持在低水平以适应芯片,并且可以手动绘制电路并验证其正确性。
编辑:Z80有大约8500个晶体管,您可能需要检查:https://en.wikipedia.org/wiki/Transistor_count和https://en.wikipedia.org/wiki/Zilog_Z80 ...并且GameBoy有点修改Z80,但总晶体管数量将非常接近虽然我没有找到确切的价值,但我不知道任天堂在未来的延伸范围内,也许他们甚至可以承受20-50k这样的东西。已经,但我对此表示怀疑。附录:最近我读到了俄罗斯Sinclair ZX Spectrum克隆,这些克隆是经过大量修改的机器,增加了额外的功率,内存和功能......其中一些使用这些nop
操作码来控制DMA传输,所以在这些机器上使用它们作为nop
的代码可能无法正确执行。这不是与GameBoy相关的,但是如果您有二进制目标,其中一个是&#34; Sprinter&#34;或类似的俄罗斯ZX克隆,你发现其中一个在反汇编中,不要自动考虑它们provider_config = {
'issuer': 'https://op.example.com',
'authorization_endpoint': 'https://op.example.com/authorize',
'token_endpoint': 'https://op.example.com/token',
'userinfo_endpoint': 'https://op.example.com/userinfo'
}
auth = OIDCAuthentication(provider_configuration_info=provider_config)
,它们可能是实际做某事的有效代码的一部分(很可能是用DMA)。
答案 1 :(得分:5)
这些好奇的NOP指令一直回到英特尔8008的原始祖先处理器。在该芯片中,它们仅仅是寄存器移动指令的实现结果。允许MOV A,A等简化了指令解码器并节省了硅空间。
从8080到Z80(及以后),这些都需要保持向后兼容性。他们甚至以
的形式存在于x86世界中MOV AL,AL等。
所以大多数现代台式机仍然支持这些奇怪的指令。
注意:我在描述英特尔机器时使用了英特尔助记符。请放心,这些组合为与Zilog助记符相同的二进制代码。