【问题标题】:Z80: Copying from Top of Stack to HLZ80:从栈顶复制到 HL
【发布时间】:2018-03-16 20:07:39
【问题描述】:

这可以通过以下方式完成:

11 pop hl
10 push hl

在 21 个周期内。我发现的唯一替代方案是ex (sp),hl,它需要 19 个周期。缺点是,一旦我完成了内容,就必须将它们交换为原始值,所以在实践中,这种方法甚至比第一种方法更昂贵。

还有其他选择吗?

【问题讨论】:

  • 我不相信您会在 Z80 上找到一种更快的机制来将堆栈顶部复制到 HL 并能够在没有更多指令的情况下将堆栈保持在当前状态。
  • 好的。我可以忍受这一点。感谢您证实我的怀疑。
  • 在 Z80 的某些变体上,例如游戏男孩,LD HL, (SP+e)
  • 什么将值放入堆栈?不能直接写到内存吗? (进入ld hl,NNNN 10t 自我修改它)... 可能是值得的,特别是如果您读取该值的次数多于编写它的次数。
  • 其实 'ld hl,(NN)' 在 Z80 上有一个优化版本。虽然可以是 ED6Bxxyy,但也可以是 2Axxyy,即 16t,3B。

标签: assembly stack micro-optimization z80


【解决方案1】:

如果您想将堆栈顶部的值放入 HL,那么您已经列出了几乎所有可用的选项:

          pop hl : push hl                               ; 10+11 = 21t

          pop hl : dec sp : dec sp                       ; 10+6+6 = 22t

你也可以自己修改代码,不会有太大好处:

          ld (addr1+1),sp
addr1:    ld hl,(0)                                      ; 20 + 16 = 36t

更尴尬的是,你可以先让SP进入HL:

          ld hl,0 : add hl,sp
          ld a,(hl) : inc hl : ld h,(hl) : ld l,a        ; 10+11 + 7+6+7+4 = 21+24 = 45t

(我提到了最后两个选项,以防万一您可以从其中一个中受益。)

命令

          ex (sp),hl                                     ; 19t

将堆栈顶部的值与 HL 的当前值交换,因此它已经不完全符合您的要求(即使它很快)。因此,进一步加快这一进程的唯一方法就是以各种方式作弊。有些作弊方法似乎最明显:

  • 如果您确实知道 SP 指向的位置,只需阅读它会更快:

         ld hl,(wherethestackis)                         ; 16t
    
  • 如果您可以控制堆栈的确切位置或堆栈实际包含的内容,则可以将其指向将值加载到 HL 中的命令,这样您就可以简单地做

         ld hl,thevalueonthestack                        ; 10t
    

我知道这两个选项看起来都很极端,但我知道很多高度优化的 Z80 代码都受益于类似的技巧。所以,请不要立即解雇他们。

【讨论】:

  • 我很欣赏你的彻底性和一些非正统的想法。不幸的是,我无法提前知道sp 会是什么,此外,我必须保留堆栈内容,因此ex (sp),hl 的效率低于pop hl : push hl。我同意将我的问题标记为“微优化”的人的观点。我承认,这是对硬件的一个相对较小的抱怨,我认为我必须满足于我最初的方法。无论如何,非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-27
  • 2012-09-20
  • 2015-07-04
  • 2018-09-20
  • 1970-01-01
  • 2022-10-17
相关资源
最近更新 更多