문제

First a little background. The z80 CPU has an instruction called DJNZ which can be used in a similar manner as a for loop. Basically DJNZ decrements the B register and jumps to a label if not zero. For example:

    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 

Of course you can do the same thing using regular comparison and jump instructions, but often it is handy to use the single instruction.

With that out of the way, my question is, do other CPU architectures include a similar control instruction?

도움이 되었습니까?

해결책

That was a fairly common instruction on machines of that era, and occurs in many other places as well.

And so on

다른 팁

Actualy in IA-32 direct equivalent for DJNZ is LOOPcc (LOOPZ). Remember the Z80 and 8086 have the same predecessor Intel 8080. So all x86 CPUs directly inherit DJNZ instruction!

IA-32 has various REP* instructions which use CX as their counter

PowerPC has bdnz and a special count-down register ctr. Decrementing ctr and conditionally branching is independent of the actual condition test, so you can add a condition on top of bdnz, eg bdnzlt cr5, label (if memory serves) will check if the less-than bit stored in cr5 and either AND or OR that with the condition of ctr becoming 0.

Ironically, ctr is also used to store any indirect function call destination. So it's possible to code the instruction "decrement ctr and branch to its new value if not zero", but this is specifically forbidden. (It wouldn't check for a NULL pointer anyway.) Somewhat significantly, bdnz becomes rather useless in a loop with an indirect call.

Some PIC microcontrollers like the PIC18 have a DECFSZ (Decrement File and Skip if Zero) instruction. I have often put a DECFSZ followed by branch.

There exist single instruction set computers, which aren't actually used. But one of the single instruction set machines is the "subtract and branch if less than or equal to zero" (subleq) machine. Wikipedia has more on this

I'm not aware of any other real machines that have an instruction exactly like this though. I like RISC machines, and really don't see a need for it either.

The PDP-11 (circa 1970) predated the Z-80 by about 5 years, and at least some models (though probably not the early ones) had a subtract-one-and-branch instruction:

sob R, offset

On x86 there is the LOOP instruction that does exactly the same thing (with counter in ECX). There is also the JECXZ instruction (Jump if ECX is Zero) which is meant to be used together with LOOP - you place it BEFORE the loop so that you can skip the entire loop if the count was zero in the beginning.

Like this:

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

But note that those instructions are horribly inefficient on contemporary CPUs. It's much better to use regular CMP/SUB and Jcc instructions. On a side note - the Intel Core2 CPUs are actually able to treat a compare+jump instruction pair as if it were a single instruction - they call it "macro-op fusion".

The Z80 was a CISC processor. DJNZ is a classic example of a complex instruction. The modern fashion is towards RISC instruction sets which prefer smaller, simpler, faster instructions but can process them more quickly - especially with advanced pipelining features. I don't think you get anything like this on the ARM family, for example.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top