开发者

Conditional Jump instructions?

Doing a compiler design course:

What is meant by a conditional jump instruction? I am C/C++ based programmer so if there is any code samples in that paradigm you could share to help me understand this better.

What do they mean by unlimited conditional jump instructions?

An example of a stateme开发者_StackOverflow中文版nt from the book:

Many processors have conditional jump instructions only for conditional jumps with a limited range. For example, the target of the jump may not be further than 128 bytes away from the current program counter. Sometimes, an assembler for such a processor still allows unlimited conditional jumps.

Would I have to know assembler programming to understand this?

I'd love links to reference materials for further reading.


Many processors have conditional jump instructions only for conditional jumps with a limited range. For example, the target of the jump may not be further than 128 bytes away from the current program counter.

Take an x86 conditional jump like JNZ for example which means "jump if the processor's Zero flag is not set" (the processor flags would be set or cleared by a previous arithmetic operation).

The JNZ opcode has an operand which says how far to jump. For the JNZ opcode the operand is encoded using a single byte (i.e. only the first byte after the opcode is interpreted as the operand; the next byte is the begining of the next opcode), so it can specify a jump of no further than plus or minus 128 bytes.

[It uses a short, 1-byte operand because a short jump is the most common case, and this optimization for the most common case helps to make the overall code smaller].

Sometimes, an assembler for such a processor still allows unlimited conditional jumps.

This means when when you write in high-level assembly, you can write ...

jnz distant_label
[other instructions]
distant_label:

... even when the distant label is more than 128 bytes away. How can it do this, when the CPU itself only supports short conditional jumps? Probably because the assembler (which 'assembles' your assembly language, like a compiler) automatically inserts some extra necessary opcodes, so that what actually ends up being emitted is something like ...

jz nearby_label
jmp distant_label
nearby_label:
[other instructions]
distant_label:

... where:

  • Instead of jnz distant_label there's jmp distant_label -- JMP is an unconditional jump, which has a larger operand and can jump an unlimited distance
  • Instead of jnz distant_label there's jz nearby_label -- 'JNZ' is replaced by 'JZ' which means instead of "jump to distant label if the flag is not zero" it does "jump to nearby label, so don't do the far jump, if the flag is zero" (which ends up meaning the same thing as what you wrote, because "jump if not zero" means the same thing as "don't jump if zero").


I think this addresses your question: in the Microchip PIC18F series, for example, you have a bra (branch) command and a goto command. They are effectively the same, but the difference is that the bra command can only jump to a location -1024 to +1023 words from its location, and it uses only one word of program memory. A goto command can jump anywhere in program memory, but it requires an two words of program memory to allow jumping anywhere.

If you incorrectly try branching to a label too far away, the compiler will give you an error.

Those extra words can make a difference when you only have, say, 2K words of program memory, of course.

bra and goto by themselves are unconditional jumps; however, there are several conditional branch commands, such as bc (branch if carry), bz (branch if zero), bnz (branch if not zero), etc, which all check the status registers from the last (arithmetic) operation, and only perform the branch if the specified condition was true.

If you need a conditional goto, then you would have something like

DELAY
    nop
    nop
    decfsnz DelayCount
    goto DONE_WITH_DELAY
    bra DELAY

Where we perform two no-ops to "sleep" for a moment; decrement a "variable" named DelayCount, and if DelayCount is zero, then we unconditionally jump to the code labeled DONE_WITH_DELAY; if it is not zero, we jump back up to the DELAY label and do it again. (decfsnz means "Decrement f, skip if not zero)


Regarding the conditional branch, you can start at this definition:

Branch (computer science):

There are two usual forms of branch instruction: a conditional branch that can be either taken or not taken, depending on a condition such as a CPU flag, and an unconditional branch which is always taken.

The if, for, while C statements are compiled to conditional jump assembly operators. While the goto statement is compiled to an unconditional jump operator.

Regarding the limited/unlimited range of the jump: The range is the "distance" in the memory between the address of the jump instruction and the address to which jumping. The Program counter article in the wikipedia can give you more information on this matter.

You don't have to know assembler programming in order to understand these subjects, but I'd recommend to learn the basics of the CPU architecture.


A conditional jump would logically turn this if statement:

if(a == b)
{
  // do something
}

// do something else

into this:

if(!(a==b)) goto somethingElse;
// do something

somethingElse:
// do something else

The if(!(a==b)) line would then turn into the assembly command:

CMP A, B
JNE somethingElse

Now, as for "unlimited conditional jump", I assume they mean far jumps?


A conditional jump is like

if (condition) goto

in C. An unconditional jump is like

goto

in C.

I don't know what "unlimited" means though. It could be specific to the particular processor under discussion.


In short terms:

Conditional means something like

if(condition)
{
  //condition met
}
else
{
  //condition no met
}

That means program flow is changed depending ot the conditional expression.

Unconditional jumps are typical compiler implementations of goto statements or function calls.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜