5. Testing Condition Codes and Branching

As you may remember when data is MOVED into a register or memory address, certain condition codes are set or unset. These codes can be used, along with the results of a CMP instruction and/or the discussion of signed and unsigned numbers above, to determine program flow. To change the flow, we use the branch instruction also known as Bcc or Branch on condition code. The genral format of a Bcc instruction is :

Bcc    label 

The label part defines where the branch will be to (the destination) and is an offset from the current program counter and of course may be positive or negative.

A branch instruction is equivalent to a SuperBasic GOTO command. Much frowned upon by purists, but useful in certain situations. Never say 'Never use a GOTO' because in assembly language you almost always have one !

There are a number of 'branch' instructions that look at the condition codes and change the course of your program according to what they find. There are 14 of these and some appear remarkably similar to others. They are :

BranchNameSigned/unsignedDescription
BCCBranch Carry ClearUnsignedThe branch is executed if the carry flag is not set - ie zero.
BCSBranch Carry SetUnsignedThe branch is executed if the carry flag is set - ie one.
BEQBranch EqualBothBranch only if the result of the last operation caused the zero flag to be set. MOVEQ #0,D0 for example.
BGEBranch Greater or EqualSignedBranch if the last operation resulted in a signed number that was zero or greater.
BGTBranch Greater ThanSignedBranch if the last result was greater that zero.
BHIBranch HigherUnsignedBranch if the last result was greater than zero.
BLEBranch Less or EqualSignedBranch if the last result was zero or less.
BLSBranch Low or SameUnsignedSame as BLE, but 'equal' replaced by 'same'.
BLTBacon Lettuce & Tomato (only kidding !) Branch Less ThanSignedBranch only if the last result was less than zero.
BMIBranch MinusSignedBranch if the result of the last operation was negative. Ie less than zero but not including zero.
BNEBranch Not EqualBothBranch if the last operation resulted in a non-zero outcome. CMPI.L #1,D1 if D1.L is not holding the value 1.
BPLBranch PlusSignedBranch if the result of the last operation is positive ie zero or greater.
BVCBranch oVerflow ClearBothbranch is the last operation left the V flag unset.
BVSBranch oVerflow SetBothbranch is the last operation left the V flag set.

There is one more branch instruction that does not care about the flags, this is the BRA or Branch unconditionally instruction. It is the most like a GOTO instruction as that is its exact purpose - goto some other place in the program.

If the displacement value will fit into a single byte (-128 to +127) then a 'short' branch will take place. This entire instruction fits into a single word. If the displacement is zero, then this would normally indicate a short branch to the next instruction in the program. As this is where the PC is pointing anyway the zero displacement is used to signify a long branch and the word folloing is used as a 16 bit displacement allowing relative values between -32768 to +32767.

The short branch is written as Bcc.S with the dot and 's' indicating the shortness. Most assemblers default to the long branch which adds 2 bytes to your program for every Bcc instruction in it. I find the 'best' way to reduce the 'wasted' bytes is to make all branches short and the assembler will reject those which are out of range.

One of the most confusing aspects of assembly language programming for new and experienced coders alike is 'which are the signed and unsigned tests ?' I always have to look it up and I have never found a place where all the tests are listed together with the signed and unsigned comparisons. You won't have this problem as I have listed them all below.

Table 2.1. Signed & Unsigned Tests

Test forSignedUnsigned
Greater EqualBGEBCC
Greater thanBGTBHI
EqualBEQBEQ
Not EqualBNEBNE
Less EqualBLEBLS
Less thanBLTBCS
NegativeBMINot applicable
PositiveBPLNot applicable

In the above description of the Bcc instructions I state, for example, that the BNE instruction will branch if the last result was not zero. This is not quite the case. If I had just loaded a data register with some value which was not zero then the branch would be taken, as in the following fragment of code :

MOVE.L    (A0),D1 
BNE.S     Somewhere 

If, on the other hand, I was comparing two registers then the branch would have been taken if they did not have exactly the same contents :

CMP.L     D3,D4 
BNE.S     not_equal
BHI.S     greater

So you can see that there are more ways to use these conditional branches. Bear in mind, however, that the CMP is simply a subtraction with the result 'thrown away' and it is that result that is being checked. One other area of confusion is which register is greater in the BHI instruction above ?

In a CMP instruction it should be read as Destination CMP source. If this is followed by a Bcc then it means branch if the destination is <condition> source. So in the above code fragment, we will branch to the label 'greater' if and only if D4 is greater than D3.

There are other instructions that affect the flow of a program and these are the 'looping' constructs or DBcc as they are written. These are the 'Decrement and branch UNTIL condition. Confused ? All will be revealed in the next chapter.