【问题标题】:Equivalents to Z80 DJNZ instruction on other architectures?相当于其他架构上的 Z80 DJNZ 指令?
【发布时间】:2010-02-22 03:20:24
【问题描述】:

首先是一点背景。 z80 CPU 有一条名为DJNZ 的指令,可以以与for 循环类似的方式使用。基本上 DJNZ 会减少 B 寄存器,如果不为零则跳转到标签。例如:

    ld      b,96                    ; erase all of the line
disp_version_erase_loop:
    call    _vputblank              ; erase pixels at cursor (uses b reg)
    djnz    disp_version_erase_loop ; loop 

当然,您可以使用常规比较和跳转指令来做同样的事情,但通常使用单条指令很方便。

除此之外,我的问题是,其他 CPU 架构是否包含类似的控制指令?

【问题讨论】:

    标签: assembly instruction-set z80


    【解决方案1】:

    实际上,在 IA-32 中,DJNZ 的直接等效项是 LOOPcc (LOOPZ)。请记住 Z80 和 8086 具有相同的前身 Intel 8080。 所以所有x86 CPU都直接继承DJNZ指令!

    【讨论】:

    • Intel 8080 没有 DJNZ 指令,它是 Z80 特有的。 DJNZ 的操作码是 8080 上的 NOP。x86 上的 LOOP 也具有与 DJNZ 完全不同的操作码。
    【解决方案2】:

    这是那个时代机器上相当普遍的指令,在许多其他地方也出现过。

    等等

    【讨论】:

      【解决方案3】:

      IA-32 有各种使用 CX 作为计数器的REP* 指令

      【讨论】:

        【解决方案4】:

        PowerPC 有一个bdnz 指令和一个特殊的倒计时寄存器ctr。递减ctr 并有条件地分支是在常规条件测试之上,因此您可以添加一个条件,例如,如果设置了小于位并且ctr 在递减后为​​正,则bdnzt eq, label 将分支。

        具有讽刺意味的是,ctr 也用于间接函数调用地址。因此,bdnz 在带有间接调用的循环中变得相当无用,因为保存和恢复它的成本超过了ctr 寄存器的特殊优势。指令存在一种编码,“递减ctr,如果不为零,则跳转到它的新值”,但这是特别禁止和限制的。 (无论如何它都不会检查 NULL 指针。)

        【讨论】:

          【解决方案5】:

          PDP-11(大约 1970 年)比 Z-80 早了大约 5 年,并且至少某些型号(尽管可能不是早期型号)具有减一和分支说明:

          sob R, offset
          

          【讨论】:

            【解决方案6】:

            一些 PIC 单片机(如 PIC18)具有 DECFSZ(递减文件,如果为零则跳过)指令。我经常放一个 DECFSZ 后跟分支。

            【讨论】:

              【解决方案7】:

              存在实际未使用的单指令集计算机。但是单指令集机器之一是“如果小于或等于零,则进行减法和分支”(subleq)机器。 Wikipedia has more on this

              我不知道有任何其他真正的机器有这样的指令。我喜欢 RISC 机器,也真的觉得没有必要。

              【讨论】:

              • 它很有用,因为循环计数器的测试不使用任何标志。无需担心标志是否用于循环中的某些内容/无论如何只有一组标志/寄存器依赖性管理不是很聪明(例如,POWER 芯片只能对条件寄存器进行 1 个重命名)。对于普通情况,递减只是一个方便的奖励。 (例如,ARM 只有比较和分支如果零/非零位。)(作为替代示例,MIPS 没有标志寄存器。这是解决此类问题的另一种方法。)
              【解决方案8】:

              在 x86 上,有一条 LOOP 指令做同样的事情(在 ECX 中使用计数器)。还有 JECXZ 指令(如果 ECX 为零则跳转),该指令旨在与 LOOP 一起使用 - 将其放在循环之前,这样如果开始时计数为零,则可以跳过整个循环。

              像这样:

                ;number of iterations in ECX
                JECXZ end
              start:
                ;loop body
                LOOP start
              end:
              

              但请注意,这些指令在当代 CPU 上效率极低。使用常规 CMP/SUB 和 Jcc 指令要好得多。附带说明 - Intel Core2 CPU 实际上能够将比较+跳转指令对视为一条指令 - 他们称之为“宏操作融合”。

              【讨论】:

                【解决方案9】:

                Z80 是 CISC 处理器。 DJNZ 是复杂指令的经典示例。现代时尚倾向于 RISC 指令集,这些指令集更喜欢更小、更简单、更快的指令,但可以更快地处理它们——尤其是使用高级流水线功能。例如,我认为你不会在 ARM 家族中得到这样的东西。

                【讨论】:

                • CBZ/CBNZ?那是一半。不过我的 ARM 有点生锈了……这可能并非在所有模式下都可用?
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2013-08-09
                • 1970-01-01
                • 2018-11-01
                • 1970-01-01
                • 1970-01-01
                • 2013-12-06
                • 2013-02-26
                相关资源
                最近更新 更多